{
 "cells": [
  {
   "cell_type": "markdown",
   "id": "80eb1898",
   "metadata": {},
   "source": [
    "**This code includes functions to downscale data using the Base Method and the Full Method described by Wang et al. (202x).**\n",
    "\n",
    "The code was originally written in Python 3.9.x. "
   ]
  },
  {
   "cell_type": "markdown",
   "id": "1fcfaea5",
   "metadata": {},
   "source": [
    "# Occupational Downscaling Code"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 16,
   "id": "002ff7ce",
   "metadata": {
    "ExecuteTime": {
     "end_time": "2024-02-13T22:31:41.718472Z",
     "start_time": "2024-02-13T22:31:41.696096Z"
    },
    "code_folding": [
     20,
     31,
     84,
     117,
     148,
     161
    ]
   },
   "outputs": [],
   "source": [
    "import pandas as pd\n",
    "import numpy as np\n",
    "import os\n",
    "import itertools\n",
    "\n",
    "## Files and folders\n",
    "FOLDER_RESULTS = './results/downscaled_data'\n",
    "FOLDER_FIGURES = './figures/'\n",
    "\n",
    "# NHGIS tract-level SEX x AGE x RACE from ACS 2015-2019\n",
    "FN_ACS_DEM = './data/nhgis0001_csv/nhgis0001_ds245_20195_tract.csv'\n",
    "# NHGIS tract-level OCC x SEX from ACS 2015-2019\n",
    "FN_ACS_EMP = './data/nhgis0001_csv/nhgis0001_ds244_20195_tract.csv'\n",
    "# BLS occupational employment data\n",
    "FN_BLS = './data/oesm17st/state_M2017_dl.xlsx'\n",
    "# CPS data for state-level characteristics\n",
    "FN_CPS = './data/cps_00023.csv.gz'\n",
    "# U.S. geographic levels (state, division, region)\n",
    "FN_GEO_LEVEL = './data/census_divison_region.xlsx'\n",
    "# Occupation crosswalk between COC and SOC\n",
    "FN_CSWLK = './data/soc_census_crosswalk.xlsx'\n",
    "\n",
    "## Global lists and dicts\n",
    "# States to keep\n",
    "LIST_STATES = ['Alabama', 'Arizona', 'Arkansas', 'California', 'Colorado',\n",
    "                'Connecticut', 'Delaware', 'District of Columbia', 'Florida',\n",
    "                'Georgia', 'Idaho', 'Illinois', 'Indiana', 'Iowa', 'Kansas',\n",
    "                'Kentucky', 'Louisiana', 'Maine', 'Maryland', 'Massachusetts',\n",
    "                'Michigan', 'Minnesota', 'Mississippi', 'Missouri', 'Montana',\n",
    "                'Nebraska', 'Nevada', 'New Hampshire', 'New Jersey', 'New Mexico',\n",
    "                'New York', 'North Carolina', 'North Dakota', 'Ohio', 'Oklahoma',\n",
    "                'Oregon', 'Pennsylvania', 'Rhode Island', 'South Carolina',\n",
    "                'South Dakota', 'Tennessee', 'Texas', 'Utah', 'Vermont',\n",
    "                'Virginia', 'Washington', 'West Virginia', 'Wisconsin', 'Wyoming']\n",
    "\n",
    "DICT_STATEFIP = {\n",
    "    1:'Alabama',\n",
    "    4:'Arizona',\n",
    "    5:'Arkansas',\n",
    "    6:'California',\n",
    "    8:'Colorado',\n",
    "    9:'Connecticut',\n",
    "    10:'Delaware',\n",
    "    11:'District of Columbia',\n",
    "    12:'Florida',\n",
    "    13:'Georgia',\n",
    "    16:'Idaho',\n",
    "    17:'Illinois',\n",
    "    18:'Indiana',\n",
    "    19:'Iowa',\n",
    "    20:'Kansas',\n",
    "    21:'Kentucky',\n",
    "    22:'Louisiana',\n",
    "    23:'Maine',\n",
    "    24:'Maryland',\n",
    "    25:'Massachusetts',\n",
    "    26:'Michigan',\n",
    "    27:'Minnesota',\n",
    "    28:'Mississippi',\n",
    "    29:'Missouri',\n",
    "    30:'Montana',\n",
    "    31:'Nebraska',\n",
    "    32:'Nevada',\n",
    "    33:'New Hampshire',\n",
    "    34:'New Jersey',\n",
    "    35:'New Mexico',\n",
    "    36:'New York',\n",
    "    37:'North Carolina',\n",
    "    38:'North Dakota',\n",
    "    39:'Ohio',\n",
    "    40:'Oklahoma',\n",
    "    41:'Oregon',\n",
    "    42:'Pennsylvania',\n",
    "    44:'Rhode Island',\n",
    "    45:'South Carolina',\n",
    "    46:'South Dakota',\n",
    "    47:'Tennessee',\n",
    "    48:'Texas',\n",
    "    49:'Utah',\n",
    "    50:'Vermont',\n",
    "    51:'Virginia',\n",
    "    53:'Washington',\n",
    "    54:'West Virginia',\n",
    "    55:'Wisconsin',\n",
    "    56:'Wyoming'\n",
    "}\n",
    "\n",
    "# Creating ACS demographic group codes\n",
    "def generate_acs_dem_dict():\n",
    "    \"\"\"Generates dict of ACS column names for each demographic group\n",
    "        Returns:\n",
    "        - dict_acs_dem_ (dict) : dict of all demographic groups {DEM_GROUP: [COLS]}\"\"\"\n",
    "    dict_acs_age = {\n",
    "        'A1': [6, 7, 8],\n",
    "        'A2': [9, 10, 11, 12],\n",
    "        'A3': [13],\n",
    "        'A4': [14, 15, 16],\n",
    "    }\n",
    "\n",
    "    dict_acs_sex = {\n",
    "        'M': 0,\n",
    "        'F': 15,\n",
    "    }\n",
    "\n",
    "    dict_acs_race = {\n",
    "        'W': ['AL4FE'],\n",
    "        'B': ['AL4GE'],\n",
    "        'A': ['AL4IE'],\n",
    "        'O': ['AL4HE','AL4JE','AL4KE','AL4LE'],\n",
    "    }\n",
    "\n",
    "    dict_acs_dem = {\n",
    "        f\"{age}-{sex}-{race}\": [f\"{race_code}{(age_code+sex_code):03d}\" for race_code in race_codes for age_code in age_codes] \\\n",
    "        for race, race_codes in dict_acs_race.items() \\\n",
    "        for sex, sex_code in dict_acs_sex.items() \\\n",
    "        for age, age_codes in dict_acs_age.items() \\\n",
    "    }\n",
    "\n",
    "    return dict_acs_dem\n",
    "\n",
    "DICT_ACS_DEM = generate_acs_dem_dict()\n",
    "DICT_ACS_EMP_COLS = {\n",
    "    'Management Occupations': ['ALY6E005', 'ALY6E041'],\n",
    "    'Business and Financial Operations Occupations': ['ALY6E006', 'ALY6E042'],\n",
    "    'Computer and Mathematical Occupations': ['ALY6E008', 'ALY6E044'],\n",
    "    'Architecture and Engineering Occupations': ['ALY6E009', 'ALY6E045'],\n",
    "    'Life, Physical, and Social Science Occupations': ['ALY6E010', 'ALY6E046'],\n",
    "    'Community and Social Service Occupations': ['ALY6E012', 'ALY6E048'],\n",
    "    'Legal Occupations': ['ALY6E013', 'ALY6E049'],\n",
    "    'Education, Training, and Library Occupations': ['ALY6E014', 'ALY6E050'],\n",
    "    'Arts, Design, Entertainment, Sports, and Media Occupations': ['ALY6E015', 'ALY6E051'],\n",
    "    'Healthcare Practitioners and Technical Occupations': ['ALY6E016', 'ALY6E052'],\n",
    "    'Healthcare Support Occupations': ['ALY6E020', 'ALY6E056'],\n",
    "    'Protective Service Occupations': ['ALY6E021', 'ALY6E057'],\n",
    "    'Food Preparation and Serving Related Occupations': ['ALY6E024', 'ALY6E060'],\n",
    "    'Building and Grounds Cleaning and Maintenance Occupations': ['ALY6E025', 'ALY6E061'],\n",
    "    'Personal Care and Service Occupations': ['ALY6E026', 'ALY6E062'],\n",
    "    'Sales and Related Occupations': ['ALY6E028', 'ALY6E064'],\n",
    "    'Office and Administrative Support Occupations': ['ALY6E029', 'ALY6E065'],\n",
    "    'Farming, Fishing, and Forestry Occupations': ['ALY6E031', 'ALY6E067'],\n",
    "    'Construction and Extraction Occupations': ['ALY6E032', 'ALY6E068'],\n",
    "    'Installation, Maintenance, and Repair Occupations': ['ALY6E033', 'ALY6E069'],\n",
    "    'Production Occupations': ['ALY6E035', 'ALY6E071'],\n",
    "    'Transportation and Material Moving Occupations': ['ALY6E036', 'ALY6E037', 'ALY6E072', 'ALY6E073']\n",
    "}\n",
    "\n",
    "LIST_DEM_GROUPS = list(DICT_ACS_DEM.keys())\n",
    "LIST_GEO_LEVELS = ['STATE','DIVISION','REGION','NATION']\n",
    "\n",
    "round_ = 4\n",
    "\n",
    "from time import perf_counter\n",
    "def time_it(func):\n",
    "    \"\"\"Executes and prints run time of the given function\n",
    "        Parameters:\n",
    "        - func (function) : function to execute\"\"\"\n",
    "    \n",
    "    def wrapper(*args, **kwargs):\n",
    "        start = perf_counter()\n",
    "        result = func(*args, **kwargs)\n",
    "        end = perf_counter()\n",
    "        print(f\"{func.__name__} took {end-start:.1f} seconds\")\n",
    "        return result\n",
    "    return wrapper\n",
    "\n",
    "def create_crossproduct_df(cross_cols, list_values=None, df_base=None):\n",
    "    \"\"\"Creates a dataframe with cross product of selected columns\n",
    "        Parameters:\n",
    "        - cross_cols (list) : column names to cross product\n",
    "        - list_values (list[list]) : list of list of values for each column\n",
    "        - df_base (pd.DataFrame) : dataframe to copy data from\n",
    "        Returns:\n",
    "        - df (pd.DataFrame) : cross-product dataframe with copied data from df_base\n",
    "        \"\"\"\n",
    "    # Creating cross-product dataframe\n",
    "    if list_values is None:\n",
    "        list_values = [list(df_base[col].unique()) for col in cross_cols]\n",
    "    df = pd.DataFrame(data=itertools.product(*list_values), columns=cross_cols)\n",
    "    \n",
    "    # Copying data from df\n",
    "    if df_base is not None:\n",
    "        # Ignore columns for merging that are not in df_base\n",
    "        cols_merge = [col for col in cross_cols if col in df_base.columns]\n",
    "        df = pd.merge(df, df_base, on=cols_merge, how='left')\n",
    "        \n",
    "    # Size check\n",
    "    lengths = [len(list_value) for list_value in list_values]\n",
    "    #print(f\"{' x '.join(map(str, lengths))} = {np.prod(lengths)}\")\n",
    "    assert np.prod(lengths) == df.shape[0]\n",
    "        \n",
    "    return df"
   ]
  },
  {
   "cell_type": "markdown",
   "id": "0198ad35",
   "metadata": {},
   "source": [
    "## Common data and functions"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 2,
   "id": "e22d027d",
   "metadata": {
    "ExecuteTime": {
     "end_time": "2024-02-13T22:02:13.747293Z",
     "start_time": "2024-02-13T22:02:03.008625Z"
    },
    "code_folding": [
     2,
     29,
     48,
     81
    ]
   },
   "outputs": [
    {
     "name": "stdout",
     "output_type": "stream",
     "text": [
      "Total number of rows in BLS-OEWS data: 34815\n",
      "Number of unique GeoIDs: 72538\n",
      "Total number of rows in ACS data: 72538\n",
      "Number of unique GeoIDs: 72538\n",
      "Total number of rows in ACS data: 72538\n",
      "Total number of rows in the crosswalk: 809\n"
     ]
    }
   ],
   "source": [
    "## Data files\n",
    "# BLS data (both methods)\n",
    "def read_bls_data(fn):\n",
    "    \"\"\"Returns a BLS-OEWS dataframe\n",
    "        Parameters:\n",
    "        - fn (str) : excel file path for BLS-OEWS data\n",
    "        Return:\n",
    "        - df (pd.DataFrame) : BLS-OEWS dataframe\"\"\"\n",
    "    \n",
    "    # Reading data\n",
    "    df = pd.read_excel(fn)\n",
    "\n",
    "    # Keeping lower 48 states and DC\n",
    "    df = df[df['STATE'].isin(LIST_STATES)]\n",
    "\n",
    "    # Keeping relevant columns only\n",
    "    df = df[['STATE', 'OCC_CODE', 'OCC_TITLE', 'OCC_GROUP', 'TOT_EMP']].copy()\n",
    "\n",
    "    # Setting missing data (**) as np.nan -- this is not equal to 0\n",
    "    df['TOT_EMP'] = pd.to_numeric(df['TOT_EMP'], errors='coerce')\n",
    "    \n",
    "    # Adding major occupation columns\n",
    "    df['OCC_CODE_MAJOR'] = df['OCC_CODE'].str.extract(r'(^.*?)\\-') + \"-0000\"\n",
    "    \n",
    "    print(f\"Total number of rows in BLS-OEWS data: {df.shape[0]}\")\n",
    "\n",
    "    return df\n",
    "\n",
    "# ACS employment (Base Method) and ACS demographics data (Full Method)\n",
    "def read_acs_data(fn):\n",
    "    \"\"\"Returns a ACS dataframe, either employment (OCC x SEX) or demographics (SEX x AGE x RACE)\n",
    "        Parameters:\n",
    "        - fn (str) : CSV file path for ACS data\n",
    "        Return:\n",
    "        - df (pd.DataFrame) : ACS dataframe\"\"\"\n",
    "    \n",
    "    # Reading data\n",
    "    df = pd.read_csv(fn, encoding='ISO-8859-1')\n",
    "\n",
    "    # Keeping lower 48 states and DC\n",
    "    df = df[df['STATE'].isin(LIST_STATES)]\n",
    "\n",
    "    print(f\"Number of unique GeoIDs: {df['GEOID'].nunique()}\")\n",
    "    print(f\"Total number of rows in ACS data: {df.shape[0]}\")\n",
    "\n",
    "    return df\n",
    "\n",
    "# Crosswalk (both methods) \n",
    "def read_crosswalk(fn, df_bls_=None):\n",
    "    \"\"\"Returns a crosswalk dataframe\n",
    "        Parameters:\n",
    "        - fn (str) : excel file path for the crosswalk\n",
    "        - df_bls_ (pd.DataFrame) : BLS-OEWS dataframe to add major occupation codes and titles (default: DF_BLS)\n",
    "        Return:\n",
    "        - df (pd.DataFrame) : dataframe with crosswalk codes and titles\"\"\"\n",
    "    \n",
    "    # Loading defaults\n",
    "    if df_bls_ is None:\n",
    "        df_bls_ = DF_BLS.copy()\n",
    "        \n",
    "    # Reading data\n",
    "    df = pd.read_excel(fn)\n",
    "\n",
    "    # Extracting major occupations from BLS-OEWS data\n",
    "    df_major_occ_ = (df_bls_[df_bls_['OCC_GROUP']=='major']\n",
    "                    .drop_duplicates(subset=['OCC_CODE'])\n",
    "                    .reset_index(drop=True)[['OCC_CODE_MAJOR','OCC_TITLE']]\n",
    "                    .rename(columns={\n",
    "                        'OCC_CODE_MAJOR':'SOC_CODE_MAJOR',\n",
    "                        'OCC_TITLE':'SOC_TITLE_MAJOR',\n",
    "                    }))\n",
    "    \n",
    "    # Adding major occupation code and title\n",
    "    df['SOC_CODE_MAJOR'] = df['SOC_CODE'].str.extract(r'(^.*?)\\-') + \"-0000\"\n",
    "    df = pd.merge(df, df_major_occ_, on='SOC_CODE_MAJOR', how=\"left\", validate='many_to_one')\n",
    "    \n",
    "    print(f\"Total number of rows in the crosswalk: {df.shape[0]}\")\n",
    "\n",
    "    return df\n",
    "\n",
    "# U.S. region info (Full Method)\n",
    "def read_region_data(fn):\n",
    "    \"\"\"Returns a dataframe with DIVISION, REGION, NATION for each STATE\n",
    "        Parameters:\n",
    "        - fn (str) : excel file path for the crosswalk\n",
    "        Return:\n",
    "        - df (pd.DataFrame) : dataframe with U.S. geographic levels\"\"\"\n",
    "    \n",
    "    # Reading data\n",
    "    df = pd.read_excel(fn)\n",
    "    \n",
    "    # Add NATION\n",
    "    df['NATION'] = 'United States'\n",
    "    \n",
    "    df = df.drop(columns=['STATEFIP'])\n",
    "    #display(df.head(2))\n",
    "    return df\n",
    "\n",
    "DF_BLS = read_bls_data(fn=FN_BLS) \n",
    "DF_ACS_EMP = read_acs_data(fn=FN_ACS_EMP)\n",
    "DF_ACS_DEM = read_acs_data(fn=FN_ACS_DEM)\n",
    "DF_CSWLK = read_crosswalk(fn=FN_CSWLK, df_bls_=DF_BLS.copy())\n",
    "DF_GEO_LEVEL = read_region_data(fn=FN_GEO_LEVEL)"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 3,
   "id": "6d7d15d7",
   "metadata": {
    "ExecuteTime": {
     "end_time": "2024-02-13T22:02:13.762368Z",
     "start_time": "2024-02-13T22:02:13.751304Z"
    }
   },
   "outputs": [],
   "source": [
    "# display(DF_ACS_EMP['ALY6E001'].value_counts())\n",
    "# df_ = dfA_base.groupby('GEOID')[['W_A_gst']].sum()\n",
    "# display(df_.value_counts())"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 4,
   "id": "8bd3cc52",
   "metadata": {
    "ExecuteTime": {
     "end_time": "2024-02-13T22:02:13.793264Z",
     "start_time": "2024-02-13T22:02:13.765369Z"
    },
    "code_folding": [
     1,
     16,
     70,
     95,
     110
    ]
   },
   "outputs": [],
   "source": [
    "# Useful functions using basic dataframes\n",
    "def get_list_occ(occ_level, df_bls_=None):\n",
    "    \"\"\"Returns a list of occupations according to the occupation level\n",
    "        Parameters:\n",
    "        - occ_level (str) : major or detailed\n",
    "        - df_bls_ (pd.DataFrame) : BLS-OEWS dataframe (default: DF_BLS)\n",
    "        Returns:\n",
    "        - list_occ (list) : list of unique occupations for the given occupation level\"\"\"\n",
    "    \n",
    "    # Loading defaults\n",
    "    if df_bls_ is None:\n",
    "        df_bls_ = DF_BLS.copy()\n",
    "        \n",
    "    list_occ = list(DF_BLS[DF_BLS['OCC_GROUP']==occ_level]['OCC_CODE'].unique())\n",
    "    return list_occ\n",
    "\n",
    "def add_occ_details(df, occ_level='major', add_occ_code=False, df_cswlk_=None):\n",
    "    \"\"\"Adds Occupation Titles for the given occ_level code\n",
    "        Parameters:\n",
    "        - df (pd.DataFrame) : dataframe with OCC_CODE\n",
    "        - occ_level (str) : major or detailed (default: 'major')\n",
    "        - add_occ_code (bool) : If True, adds OCC_CODE for given OCC_TITLE; otherwise adds OCC_TITLE\n",
    "        - df_cswlk_ (pd.DataFrame) : crosswalk between SOC and COC codes (default: DF_CSWLK)\n",
    "        Returns:\n",
    "        - df (pd.DataFrame) : dataframe with OCC_CODE and OCC_TITLE\"\"\"\n",
    "    \n",
    "    # Loading defaults\n",
    "    if df_cswlk_ is None:\n",
    "        df_cswlk_ = DF_CSWLK.copy()\n",
    "        \n",
    "    # Crosswalk between COC code and relevant SOC code (major or detailed)\n",
    "    col_occ = 'SOC_CODE' if occ_level=='detailed' else 'SOC_CODE_MAJOR' if occ_level=='major' else np.nan    \n",
    "    col_occ_title = 'SOC_TITLE' if occ_level=='detailed' else 'SOC_TITLE_MAJOR' if occ_level=='major' else np.nan\n",
    "\n",
    "    df_cswlk_ = (df_cswlk_[[col_occ, col_occ_title]]\n",
    "                     .copy()\n",
    "                     .drop_duplicates() # very important to avoid double counting for major occupations\n",
    "                     .rename(columns={\n",
    "                         col_occ:'OCC_CODE',\n",
    "                         col_occ_title:'OCC_TITLE',\n",
    "                     }))\n",
    "    \n",
    "    assert ('OCC_CODE' in df.columns or 'OCC_TITLE' in df.columns)\n",
    "    \n",
    "    ## Adding OCC_CODE or OCC_TITLE to df\n",
    "    shape_check = df.shape[0]\n",
    "    \n",
    "    if add_occ_code:\n",
    "        # Add OCC_CODE\n",
    "        if 'OCC_CODE' in df.columns:\n",
    "            df = df.drop(columns=['OCC_CODE'])\n",
    "        df = pd.merge(df, df_cswlk_, on='OCC_TITLE', how='left')\n",
    "    else:\n",
    "        # Add OCC_TITLE\n",
    "        if 'OCC_TITLE' in df.columns:\n",
    "            df = df.drop(columns=['OCC_TITLE'])\n",
    "\n",
    "        shape_check = df.shape[0]\n",
    "        df = pd.merge(df, df_cswlk_, on='OCC_CODE', how='left')\n",
    "        \n",
    "    assert shape_check == df.shape[0] # Validate number of rows remain unchanged\n",
    "    \n",
    "    # Reorder columns\n",
    "    first_cols = ['OCC_CODE','OCC_TITLE']\n",
    "    other_cols = [col for col in df.columns if col not in first_cols]\n",
    "    new_column_order = first_cols + other_cols\n",
    "    df = df[new_column_order]\n",
    "\n",
    "    return df\n",
    "\n",
    "def add_geo_level(df, geo_level=None, df_geo_level_=None):\n",
    "    \"\"\"Adds U.S. geographic levels to a dataframe with STATEs\n",
    "        Parameters:\n",
    "        - df (pd.DataFrame) : dataframe with STATE\n",
    "        - geo_level (str) : geograhic level to add ('DIVISION','REGION','NATION','all')\n",
    "        - df_geo_level_ (pd.DataFrame) : dataframe with geographic information (default: DF_GEO_LEVEL)\n",
    "        Returns:\n",
    "        - df (pd.DataFrame) : dataframe with added geographic level\"\"\"\n",
    "    \n",
    "    # Loading defaults\n",
    "    if df_geo_level_ is None:\n",
    "        df_geo_level_ = DF_GEO_LEVEL.copy()\n",
    "    \n",
    "    # Adding relevant columns\n",
    "    if geo_level == 'STATE':\n",
    "        pass\n",
    "    elif geo_level in LIST_GEO_LEVELS or geo_level is None:\n",
    "        df = pd.merge(df, df_geo_level_[['STATE',geo_level]], how='left', on='STATE', validate='many_to_one')\n",
    "    elif geo_level == 'all':\n",
    "        df = pd.merge(df, df_geo_level_, how='left', on='STATE', validate='many_to_one')\n",
    "    else:\n",
    "        pass\n",
    "        \n",
    "    return df\n",
    "\n",
    "def compute_rmse(df, col1, col2, typ='percent'):\n",
    "    \"\"\"Returns Root Mean Square Error between the given columns\n",
    "        Parameters:\n",
    "        - df (pd.DataFrame) : dataframe with columns (can be a grouped .groupby() dataframe)\n",
    "        - col1, col2 (str) : column names\n",
    "        - typ (str) : 'percent' or 'percentage' will convert values to % for computing RMSE\n",
    "        Returns:\n",
    "        - rmse (float) : root mean square error\"\"\"\n",
    "    \n",
    "    rmse = np.sqrt(((df[col1] - df[col2]) ** 2).mean())\n",
    "    if typ == 'percent' or typ == 'percentage':\n",
    "        rmse *= 100\n",
    "    return rmse\n",
    "\n",
    "# Data-related functions\n",
    "def prep_dfB(occ_level, df_bls_=None):\n",
    "    \"\"\"Prepares BLS-OEWS based dataframe for all occupations based on the occupation level\n",
    "        Parameters:\n",
    "        - occ_level (str) : 'major' or 'detailed'\n",
    "        - df_bls_ (pd.DataFrame) : BLS-OEWS raw dataframe (default: DF_BLS)\n",
    "        Returns:\n",
    "        - dfB_ (pd.DataFrame) : BLS-OEWS dataframe containing 'W_B_os'\"\"\"\n",
    "    \n",
    "    # Loading defaults\n",
    "    if df_bls_ is None:\n",
    "        df_bls_ = DF_BLS.copy()\n",
    "        \n",
    "    # Preparing base dataframe with 'W_B_os'\n",
    "    df_base = (df_bls_[df_bls_['OCC_GROUP']==occ_level][['STATE','OCC_CODE','TOT_EMP']]\n",
    "               .copy()\n",
    "               .rename(columns={\n",
    "                   'TOT_EMP': 'W_B_os'\n",
    "               }))    \n",
    "    \n",
    "    # Creating full SxO dataframe and copying base data\n",
    "    cross_cols = ['STATE','OCC_CODE']\n",
    "    list_occupations = get_list_occ(occ_level)\n",
    "    dfB_ = create_crossproduct_df(cross_cols=cross_cols, list_values=[LIST_STATES, list_occupations])\n",
    "    \n",
    "    # Merging W_B_os from df_base while keeping missing rows as 0 (and ** as np.nan from df_base)\n",
    "    dfB_ = pd.merge(dfB_, df_base, on=cross_cols, how='left', indicator=True)\n",
    "    dfB_.loc[(dfB_._merge=='left_only'), 'W_B_os'] = 0\n",
    "    dfB_.drop(columns=['_merge'], inplace=True)\n",
    "\n",
    "    return dfB_"
   ]
  },
  {
   "cell_type": "markdown",
   "id": "4fbdff49",
   "metadata": {},
   "source": [
    "# Base Method"
   ]
  },
  {
   "cell_type": "markdown",
   "id": "0fb97659",
   "metadata": {},
   "source": [
    "$$\n",
    "X^{A^{'}}_{st} = \\frac{ W^{A^{'}}_{st} }{ \\sum_{t\\in T_s} W^{A^{'}}_{st} } \\qquad \\forall s,t \\tag{1}\n",
    "$$\n",
    "\n",
    "$$\n",
    "W^{*'}_{ost} = W^{B}_{os} \\times X^{A^{'}}_{st} \\qquad \\forall o,s,t \\tag{2}\n",
    "$$"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 5,
   "id": "14083e56",
   "metadata": {
    "ExecuteTime": {
     "end_time": "2024-02-13T22:02:13.824469Z",
     "start_time": "2024-02-13T22:02:13.800140Z"
    },
    "code_folding": [
     1,
     24,
     51
    ]
   },
   "outputs": [],
   "source": [
    "# Base method functions\n",
    "def prep_dfA1(df_acs_emp_=None):\n",
    "    \"\"\"Prepares ACS dataframe for the base method and get 'X_A1_st' from 'W_A1_st' for each state\n",
    "        Parameters:\n",
    "        - df_acs_emp_ (pd.DataFrame) : ACS employment raw dataframe (default: DF_ACS_EMP)\n",
    "        Returns:\n",
    "        - dfA1 (pd.DataFrame) : ACS dataframe containing 'W_A1_st' and 'X_A1_st'\"\"\"\n",
    "    \n",
    "    # Loading defaults\n",
    "    if df_acs_emp_ is None:\n",
    "        df_acs_emp_ = DF_ACS_EMP.copy()\n",
    "        \n",
    "    # Reading total employment numbers from ACS\n",
    "    dfA1 = (df_acs_emp_[['GEOID','STATE','TRACTA','ALY6E001']]\n",
    "            .copy()\n",
    "            .rename(columns={\n",
    "                'ALY6E001':'W_A1_st' # Total civilians employed\n",
    "            }))\n",
    "    \n",
    "    # Computing 'X_A1_st'\n",
    "    dfA1['X_A1_st'] = dfA1['W_A1_st'] / dfA1.groupby('STATE')['W_A1_st'].transform('sum')\n",
    "    \n",
    "    return dfA1\n",
    "\n",
    "def get_W_S1_ost(dfA1, dfB, occ_code):\n",
    "    \"\"\"Computes 'W_S1_ost' from 'X_A1_st' and 'W_B_os' for each occupation and state.\n",
    "        Parameters:\n",
    "        - dfA1 (pd.DataFrame) : Dataframe containing 'X_A1_st' (ACS data)\n",
    "        - dfB (pd.DataFrame) : Dataframe containing 'W_B_os' (BLS-OEWS data)\n",
    "        - occ_code (str) : Specific occupation code to include\n",
    "        Returns:\n",
    "        - dfS1 (pd.DataFrame) : The final base method dataframe containing 'W_S1_ost'\n",
    "        \"\"\"\n",
    "\n",
    "    # Creating dataframe with all TRACTs\n",
    "    list_tracts = list(dfA1['GEOID'].unique())\n",
    "    dfS1 = create_crossproduct_df(cross_cols=['GEOID','OCC_CODE'], \n",
    "                                   list_values=[list_tracts, [occ_code]], \n",
    "                                   df_base=dfA1)\n",
    "    \n",
    "    # Merge 'W_B_os' on occupation and states\n",
    "    shape_check = dfS1.shape[0]\n",
    "    dfS1 = pd.merge(dfS1, dfB, on=['STATE','OCC_CODE'], how='left')\n",
    "    assert shape_check == dfS1.shape[0]\n",
    "    \n",
    "    # Computing 'W_S1_ost'\n",
    "    dfS1['W_S1_ost'] = dfS1['W_B_os'] * dfS1['X_A1_st']\n",
    "    \n",
    "    return dfS1\n",
    "\n",
    "#@time_it\n",
    "def run_base_method(occ_level, occ_code, display_full=False, folder_df=None,\n",
    "                    df_acs_emp_=None, df_bls_=None, df_cswlk_=None):\n",
    "    \"\"\"Downscale occupations using the base method\n",
    "        Parameters:\n",
    "        - occ_level (str): 'major' or 'detailed'\n",
    "        - occ_code (str) : specific occupation code to compute 'W_S1_ost'\n",
    "        - display_full (bool) : display heads of all computed dataframes (dfA, dfB, dfS1)\n",
    "        - folder_df (str) : folder to save results (None : no saving)\n",
    "        - df_acs_emp_ (pd.DataFrame) : ACS employment dataframe (default: DF_ACS_EMP)\n",
    "        - df_bls_ (pd.DataFrame) : BLS-OEWS dataframe (default: DF_BLS)\n",
    "        - df_cswlk_ (pd.DataFrame) : crosswalk between SOC and COC codes (default: DF_CSWLK)\n",
    "        Returns:\n",
    "        - dfS1 (pd.DataFrame) : final base method dataframe containing 'W_S1_ost'\n",
    "    \"\"\"\n",
    "    \n",
    "    # Loading defaults\n",
    "    if df_acs_emp_ is None:\n",
    "        df_acs_emp_ = DF_ACS_EMP.copy()\n",
    "    if df_bls_ is None:\n",
    "        df_bls_ = DF_BLS.copy()\n",
    "    if df_cswlk_ is None:\n",
    "        df_cswlk_ = DF_CSWLK.copy()\n",
    "        \n",
    "    # dfA1 with 'X_A1_st'\n",
    "    dfA1 = prep_dfA1(df_acs_emp_=df_acs_emp_)\n",
    "    \n",
    "    # dfB with 'W_B_os'\n",
    "    dfB = prep_dfB(occ_level=occ_level, df_bls_=df_bls_)\n",
    "        \n",
    "    ## Results dataframe\n",
    "    dfS1 = (get_W_S1_ost(dfA1=dfA1, dfB=dfB, occ_code=occ_code)\n",
    "            .pipe(add_occ_details, occ_level=occ_level, df_cswlk_=df_cswlk_))\n",
    "\n",
    "    if folder_df:\n",
    "        fn = os.path.join(folder_df, f\"{occ_code}_BASE.csv\")\n",
    "        dfS1.drop(columns=['OCC_CODE','OCC_TITLE']).round(round_).to_csv(fn, index=False)\n",
    "            \n",
    "    if display_full:\n",
    "        print(f\"Total number of rows in dfA1: {dfA1.shape[0]}\")\n",
    "        display(dfA1.head())\n",
    "        print(f\"Total number of rows in dfB: {dfB.shape[0]}\")\n",
    "        display(dfB.head())\n",
    "        print(f\"Total number of rows in dfS1: {dfS1.shape[0]}\")\n",
    "        display(dfS1.head())\n",
    "        \n",
    "    return dfS1"
   ]
  },
  {
   "cell_type": "markdown",
   "id": "cdbbe07f",
   "metadata": {},
   "source": [
    "## Example"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 6,
   "id": "8421b97b",
   "metadata": {
    "ExecuteTime": {
     "end_time": "2024-02-13T22:02:13.839581Z",
     "start_time": "2024-02-13T22:02:13.828006Z"
    },
    "code_folding": []
   },
   "outputs": [],
   "source": [
    "# # Single occupation test\n",
    "# occ_level = 'detailed'\n",
    "# occ_code = '53-7073'\n",
    "# df = run_base_method(occ_level=occ_level, occ_code=occ_code)\n",
    "# display(df.head())\n",
    "\n",
    "# # Diagnostics (use '53-7073')\n",
    "# print(f\"Tract data available for: {df.dropna(subset=['X_A1_st']).shape[0]}\")\n",
    "# print(f\"Non-zero tract data available for: {df[df['X_A1_st']>0].shape[0]}\")\n",
    "# print(f\"BLS data available for: {df.dropna(subset=['W_B_os']).shape[0]}\")\n",
    "# print(f\"Non-zero BLS data available for: {df[df['W_B_os']>0].shape[0]}\")\n",
    "# print(f\"Estimated data available for: {df.dropna(subset=['W_S1_ost']).shape[0]}\")\n",
    "# print(f\"Non-zero estimated data available for: {df[df['W_S1_ost']>0].shape[0]}\")"
   ]
  },
  {
   "cell_type": "markdown",
   "id": "ae9b34fb",
   "metadata": {},
   "source": [
    "# Full Method\n",
    "\n",
    "- Remove CPSID = 0\n",
    "- Use ASECWT"
   ]
  },
  {
   "cell_type": "markdown",
   "id": "564e486c",
   "metadata": {},
   "source": [
    "$$\n",
    "X^{C}_{gor} = \\frac{ W^{C}_{gor} }{ \\sum_{g \\in G} W^{C}_{gor} } \\qquad \\forall g,o,r \\tag{4}\n",
    "$$\n",
    "\n",
    "$$\n",
    "W^{BC}_{gos} = W^{B}_{os} \\times X^{C}_{gor} \\qquad \\forall g,o,r,s \\in S_{r} \\tag{5}\n",
    "$$\n",
    "\n",
    "$$\n",
    "X^{A}_{gst} = \\frac{ W^{A}_{gst} }{ \\sum_{t\\in T_s} W^{A}_{gst} } \\qquad \\forall g,s,t \\tag{6}\n",
    "$$\n",
    "\n",
    "$$\n",
    "W^{*}_{gost} = W^{BC}_{gos} \\times X^{A}_{gst} \\qquad \\forall g,o,s,t \\tag{7}\n",
    "$$\n",
    "\n",
    "$$\n",
    "W^{*}_{ost} = \\sum_{g \\in G} W^{*}_{gost} \\qquad \\forall o,s,t \\tag{8}\n",
    "$$"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 7,
   "id": "5ebfaa02",
   "metadata": {
    "ExecuteTime": {
     "end_time": "2024-02-13T22:02:22.026888Z",
     "start_time": "2024-02-13T22:02:13.843122Z"
    },
    "code_folding": [
     2,
     9,
     24,
     33,
     51,
     62,
     107
    ]
   },
   "outputs": [
    {
     "name": "stdout",
     "output_type": "stream",
     "text": [
      "Total number of rows in raw CPS data: 185914\n",
      "Number of rows with employed workers: 84257\n",
      "Number of rows with demographic group: 84257\n",
      "Number of rows with matching state: 81741\n",
      "Number of rows with valid occupation: 81055\n"
     ]
    },
    {
     "data": {
      "text/html": [
       "<div>\n",
       "<style scoped>\n",
       "    .dataframe tbody tr th:only-of-type {\n",
       "        vertical-align: middle;\n",
       "    }\n",
       "\n",
       "    .dataframe tbody tr th {\n",
       "        vertical-align: top;\n",
       "    }\n",
       "\n",
       "    .dataframe thead th {\n",
       "        text-align: right;\n",
       "    }\n",
       "</style>\n",
       "<table border=\"1\" class=\"dataframe\">\n",
       "  <thead>\n",
       "    <tr style=\"text-align: right;\">\n",
       "      <th></th>\n",
       "      <th>CPSIDP</th>\n",
       "      <th>STATEFIP</th>\n",
       "      <th>PERNUM</th>\n",
       "      <th>ASECWT</th>\n",
       "      <th>AGE</th>\n",
       "      <th>SEX</th>\n",
       "      <th>RACE</th>\n",
       "      <th>COC_CODE</th>\n",
       "      <th>CLASSWLY</th>\n",
       "      <th>DEM_GROUP</th>\n",
       "      <th>STATE</th>\n",
       "      <th>REGION</th>\n",
       "      <th>DIVISION</th>\n",
       "      <th>NATION</th>\n",
       "    </tr>\n",
       "  </thead>\n",
       "  <tbody>\n",
       "    <tr>\n",
       "      <th>0</th>\n",
       "      <td>20170302971501</td>\n",
       "      <td>23</td>\n",
       "      <td>1</td>\n",
       "      <td>663.54</td>\n",
       "      <td>55</td>\n",
       "      <td>1</td>\n",
       "      <td>100</td>\n",
       "      <td>7200</td>\n",
       "      <td>22</td>\n",
       "      <td>A3-M-W</td>\n",
       "      <td>Maine</td>\n",
       "      <td>Northeast Region</td>\n",
       "      <td>New England Division</td>\n",
       "      <td>United States</td>\n",
       "    </tr>\n",
       "    <tr>\n",
       "      <th>1</th>\n",
       "      <td>20170302971502</td>\n",
       "      <td>23</td>\n",
       "      <td>2</td>\n",
       "      <td>663.54</td>\n",
       "      <td>42</td>\n",
       "      <td>2</td>\n",
       "      <td>100</td>\n",
       "      <td>3600</td>\n",
       "      <td>22</td>\n",
       "      <td>A2-F-W</td>\n",
       "      <td>Maine</td>\n",
       "      <td>Northeast Region</td>\n",
       "      <td>New England Division</td>\n",
       "      <td>United States</td>\n",
       "    </tr>\n",
       "  </tbody>\n",
       "</table>\n",
       "</div>"
      ],
      "text/plain": [
       "           CPSIDP  STATEFIP  PERNUM  ASECWT  AGE  SEX  RACE  COC_CODE  \\\n",
       "0  20170302971501        23       1  663.54   55    1   100      7200   \n",
       "1  20170302971502        23       2  663.54   42    2   100      3600   \n",
       "\n",
       "   CLASSWLY DEM_GROUP  STATE            REGION              DIVISION  \\\n",
       "0        22    A3-M-W  Maine  Northeast Region  New England Division   \n",
       "1        22    A2-F-W  Maine  Northeast Region  New England Division   \n",
       "\n",
       "          NATION  \n",
       "0  United States  \n",
       "1  United States  "
      ]
     },
     "metadata": {},
     "output_type": "display_data"
    },
    {
     "data": {
      "text/html": [
       "<div>\n",
       "<style scoped>\n",
       "    .dataframe tbody tr th:only-of-type {\n",
       "        vertical-align: middle;\n",
       "    }\n",
       "\n",
       "    .dataframe tbody tr th {\n",
       "        vertical-align: top;\n",
       "    }\n",
       "\n",
       "    .dataframe thead th {\n",
       "        text-align: right;\n",
       "    }\n",
       "</style>\n",
       "<table border=\"1\" class=\"dataframe\">\n",
       "  <thead>\n",
       "    <tr style=\"text-align: right;\">\n",
       "      <th></th>\n",
       "      <th>GEOID</th>\n",
       "      <th>STATE</th>\n",
       "      <th>DEM_GROUP</th>\n",
       "      <th>W_A_gst</th>\n",
       "      <th>X_A_gst</th>\n",
       "    </tr>\n",
       "  </thead>\n",
       "  <tbody>\n",
       "    <tr>\n",
       "      <th>0</th>\n",
       "      <td>14000US01001020100</td>\n",
       "      <td>Alabama</td>\n",
       "      <td>A1-M-W</td>\n",
       "      <td>100</td>\n",
       "      <td>0.000481</td>\n",
       "    </tr>\n",
       "    <tr>\n",
       "      <th>1</th>\n",
       "      <td>14000US01001020200</td>\n",
       "      <td>Alabama</td>\n",
       "      <td>A1-M-W</td>\n",
       "      <td>51</td>\n",
       "      <td>0.000245</td>\n",
       "    </tr>\n",
       "  </tbody>\n",
       "</table>\n",
       "</div>"
      ],
      "text/plain": [
       "                GEOID    STATE DEM_GROUP  W_A_gst   X_A_gst\n",
       "0  14000US01001020100  Alabama    A1-M-W      100  0.000481\n",
       "1  14000US01001020200  Alabama    A1-M-W       51  0.000245"
      ]
     },
     "metadata": {},
     "output_type": "display_data"
    },
    {
     "name": "stdout",
     "output_type": "stream",
     "text": [
      "Total number of rows in dfA_base: 2321216\n",
      "Number of rows with 0 workers in dfA_base: 816158\n",
      "Number of rows with non-zero workers in dfA_base: 1505058\n"
     ]
    }
   ],
   "source": [
    "## Full Method common dataframes - prepare once to save time\n",
    "# CPS data (DF_CPS)\n",
    "def read_cps_data(fn):\n",
    "    \"\"\"Returns a CPS dataframe\n",
    "        Parameters:\n",
    "        - fn (str) : CSV file path for CPS data\n",
    "        Return:\n",
    "        - df (pd.DataFrame) : CPS dataframe\"\"\"\n",
    "    \n",
    "    def get_age_group(age):\n",
    "        \"\"\"Returns Age code for CPS data\"\"\"\n",
    "        if age <= 14:\n",
    "            return np.nan\n",
    "        elif 15 <= age <= 24:\n",
    "            return \"A1\"\n",
    "        elif 25 <= age <= 54:\n",
    "            return \"A2\"\n",
    "        elif 55 <= age <= 64:\n",
    "            return \"A3\"\n",
    "        elif 65 <= age:\n",
    "            return \"A4\"\n",
    "        else:\n",
    "            return np.nan\n",
    "\n",
    "    def get_sex_group(sex):\n",
    "        \"\"\"Returns Sex code for CPS data\"\"\"\n",
    "        if sex == 1:\n",
    "            return \"M\"\n",
    "        elif sex == 2:\n",
    "            return \"F\"\n",
    "        else:\n",
    "            return np.nan\n",
    "\n",
    "    def get_race_group(race):\n",
    "        \"\"\"Returns Race code for CPS data\"\"\"\n",
    "        # White\n",
    "        if race == 100:\n",
    "            return \"W\"\n",
    "        # Black\n",
    "        elif race == 200:\n",
    "            return \"B\"\n",
    "        # Asian alone\n",
    "        elif race == 651: \n",
    "            return \"A\"\n",
    "        # Missing\n",
    "        elif race == 999:\n",
    "            return np.nan\n",
    "        # Everyone else\n",
    "        else:\n",
    "            return \"O\"\n",
    "\n",
    "    def get_dem_group(age, sex, race):\n",
    "        \"\"\"Returns demographic group in th AGE-SEX-RACE format\"\"\"\n",
    "        age_group = get_age_group(age)\n",
    "        sex_group = get_sex_group(sex)\n",
    "        race_group = get_race_group(race)\n",
    "\n",
    "        if (age_group is np.nan) or (sex_group is np.nan) or (race_group is np.nan):\n",
    "            return np.nan\n",
    "        else:\n",
    "            return f\"{age_group}-{sex_group}-{race_group}\"\n",
    "\n",
    "    def get_state(statefip):\n",
    "        \"\"\"Returns State name from STATEFIP\"\"\"\n",
    "        if statefip in DICT_STATEFIP.keys():\n",
    "            return DICT_STATEFIP[statefip]\n",
    "        else:\n",
    "            return np.nan\n",
    "    \n",
    "    # Reading data\n",
    "    df = pd.read_csv(fn)\n",
    "    df = df[['CPSIDP','STATEFIP','PERNUM','ASECWT','AGE','SEX','RACE','OCCLY','CLASSWLY']]\n",
    "    print(f\"Total number of rows in raw CPS data: {df.shape[0]}\")\n",
    "    \n",
    "    #! Keeping oversampled data as it is considered in ASECWT \n",
    "    # Remove oversampled data (CPSIDP = 0)\n",
    "    #mask = (df['CPSIDP']>0)\n",
    "    #df = df[mask].copy()\n",
    "    #print(f\"Number of rows after removing oversampled data: {df.shape[0]}\")\n",
    "    \n",
    "    # Remove rows that do not match COC occupations from crosswalk\n",
    "    mask = (df['CLASSWLY']>=20) & (df['CLASSWLY']<=29) # Institutional workers only (to match BLS-OEWS)\n",
    "    #mask = (df['CLASSWLY']>15) # Institutional workers only (to match BLS-OEWS) - same as >=20 and <= 29\n",
    "    df = df[mask].copy()\n",
    "    print(f\"Number of rows with employed workers: {df.shape[0]}\")\n",
    "    \n",
    "    # Remove non-sociodemographic items\n",
    "    df['DEM_GROUP'] = df.apply(lambda x: get_dem_group(x['AGE'], x['SEX'], x['RACE']), axis=1)\n",
    "    df = df.dropna(subset=['DEM_GROUP']).copy()\n",
    "    print(f\"Number of rows with demographic group: {df.shape[0]}\")\n",
    "    \n",
    "    # Keep 48 states and DC\n",
    "    df['STATE'] = df['STATEFIP'].apply(get_state)\n",
    "    df = df.dropna(subset=['STATE']).copy()\n",
    "    print(f\"Number of rows with matching state: {df.shape[0]}\")\n",
    "    \n",
    "    # Remove rows that do not match COC occupations from crosswalk\n",
    "    df = df.rename(columns={'OCCLY':'COC_CODE'})\n",
    "    df = df[df['COC_CODE'].isin(DF_CSWLK['COC_CODE'].unique())].copy()\n",
    "    print(f\"Number of rows with valid occupation: {df.shape[0]}\")\n",
    "    \n",
    "    # Add geographic level information\n",
    "    df = df.pipe(add_geo_level, geo_level='all')\n",
    "    \n",
    "    return df\n",
    "\n",
    "# ACS-based data (dfA)\n",
    "def prep_dfA(df_acs_dem_=None, dict_acs_dem=None, list_dem_groups=None):\n",
    "    \"\"\"Prepares ACS dataframe for the Full Method with each tract and demographic group (cross product)\n",
    "        Parameters:\n",
    "        - df_acs_dem_ (pd.DataFrame) : ACS raw dataframe (default: DF_ACS_DEM)\n",
    "        - dict_acs_dem (dict) : dictionary linking demographic groups to ACS columns (default: DICT_ACS_DEM)\n",
    "        - list_dem_groups (list) : list of demographic groups for analysis (default: LIST_DEM_GROUPS)\n",
    "        Returns:\n",
    "        - dfA (pd.DataFrame) : dataframe containing 'W_A_gst'\"\"\"\n",
    "    \n",
    "    # Loading defaults\n",
    "    if df_acs_dem_ is None:\n",
    "        df_acs_dem_ = DF_ACS_DEM.copy()\n",
    "    if dict_acs_dem is None:\n",
    "        dict_acs_dem = DICT_ACS_DEM\n",
    "    if list_dem_groups is None:\n",
    "        list_dem_groups = LIST_DEM_GROUPS\n",
    "\n",
    "    dfA = df_acs_dem_.copy()\n",
    "    # Combining same demographic columns\n",
    "    for dem_group, cols in dict_acs_dem.items():\n",
    "        dfA[dem_group] = dfA[cols].sum(axis=1)\n",
    "\n",
    "    # Creating cross-product of TRACT x DEM_GROUP\n",
    "    dfA = dfA[['GEOID','STATE'] + list_dem_groups]\n",
    "    dfA = dfA.melt(id_vars=['GEOID','STATE'], value_vars=list_dem_groups, var_name='DEM_GROUP', value_name='W_A_gst')\n",
    "    assert dfA.shape[0] == (dfA['GEOID'].nunique() * len(list_dem_groups))\n",
    "    \n",
    "    # Setting zero workers tract to NaN (treated as missing data) --> helps with diagnostic computations\n",
    "    #dfA['W_A_gst'] = dfA['W_A_gst'].replace(0, np.nan) \n",
    "    \n",
    "    # Mean over all tracts in the given state\n",
    "    dfA['X_A_gst'] = dfA['W_A_gst'] / dfA.groupby(['STATE','DEM_GROUP'])['W_A_gst'].transform('sum')\n",
    "    return dfA\n",
    "\n",
    "    #print(f\"{DF_ACS_DEM['GEOID'].nunique()} * {len(list_dem_groups)} = {DF_ACS_DEM['GEOID'].nunique()*len(list_dem_groups)}\")\n",
    "    #print(f\"Total number of rows in dfA: {dfA.shape[0]}\")\n",
    "    \n",
    "    return dfA\n",
    "\n",
    "DF_CPS = read_cps_data(fn=FN_CPS)\n",
    "\n",
    "display(DF_CPS.head(2))\n",
    "\n",
    "dfA_base = prep_dfA(df_acs_dem_=DF_ACS_DEM.copy())\n",
    "\n",
    "display(dfA_base.head(2))\n",
    "print(f\"Total number of rows in dfA_base: {dfA_base.shape[0]}\")\n",
    "print(f\"Number of rows with 0 workers in dfA_base: {(dfA_base.W_A_gst==0).sum()}\")\n",
    "print(f\"Number of rows with non-zero workers in dfA_base: {(dfA_base.W_A_gst>0).sum()}\")"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 8,
   "id": "dddea496",
   "metadata": {
    "ExecuteTime": {
     "end_time": "2024-02-13T22:02:22.057142Z",
     "start_time": "2024-02-13T22:02:22.029392Z"
    },
    "code_folding": [
     2,
     76,
     90,
     109,
     131
    ]
   },
   "outputs": [],
   "source": [
    "## Full Method functions \n",
    "# CPS-based data (dfC)\n",
    "def prep_dfC(region_level, occ_code, occ_level, weights='ASECWT', df_geo_level_=None, df_cps_=None, df_cswlk_=None):\n",
    "    \"\"\"Adds CPS-based W_C_gor and X_C_gor to dfC for the given region_level\n",
    "        Parameters:\n",
    "        - region_level (str) : STATE, REGION, DIVISION, NATION\n",
    "        - occ_code (str) : specific occupation code to include\n",
    "        - occ_level (str) : 'major' or 'detailed'\n",
    "        - weights (str) : if 'ASECWT', use weights column to get number of workers (set None for no weights)\n",
    "        - df_geo_level_ (pd.DataFrame) : dataframe with geographic information (default: DF_GEO_LEVEL)\n",
    "        - df_cps_ (pd.DataFrame) : CPS raw data to count workers (default: DF_CPS)\n",
    "        - df_cswlk_ (pd.DataFrame) : crosswalk between SOC and COC codes (default: DF_CSWLK)\n",
    "        Returns:\n",
    "        - dfC (pd.DataFrame) : dataframe with STATE x OCC_CODE x DEM_GROUP containing 'W_C_gor' and 'X_C_gor'\n",
    "    \"\"\"\n",
    "    \n",
    "    # Loading defaults\n",
    "    if df_geo_level_ is None:\n",
    "        df_geo_level_ = DF_GEO_LEVEL.copy()\n",
    "    if df_cps_ is None:\n",
    "        df_cps_ = DF_CPS.copy()\n",
    "    if df_cswlk_ is None:\n",
    "        df_cswlk_ = DF_CSWLK.copy()\n",
    "        \n",
    "    ## Create base dfC\n",
    "    # Adding region_level for individual states for larger region_level\n",
    "    if region_level != 'STATE':\n",
    "        df_geo_level_[['STATE',region_level]]\n",
    "    else:\n",
    "        df_geo_level_[['STATE']]\n",
    "        \n",
    "    # Create dfC with STATE x OCC_CODE x DEM_GROUP dataframe with region_level\n",
    "    dfC = create_crossproduct_df(cross_cols=['STATE', 'OCC_CODE', 'DEM_GROUP'],\n",
    "                                list_values=[LIST_STATES, [occ_code], LIST_DEM_GROUPS],\n",
    "                                df_base=df_geo_level_)\n",
    "    \n",
    "    # Add OCC_TITLE\n",
    "    dfC = dfC.pipe(add_occ_details, occ_level=occ_level)\n",
    "\n",
    "    \n",
    "    ## Crosswalk between COC code and relevant SOC code ('major' or 'detailed')\n",
    "    col_occ = 'SOC_CODE' if occ_level=='detailed' else 'SOC_CODE_MAJOR' if occ_level=='major' else np.nan\n",
    "    df_cswlk_temp = (df_cswlk_[['COC_CODE', col_occ]]\n",
    "                 .drop_duplicates() # important to avoid double counting for major occupations\n",
    "                 .rename(columns={col_occ:'OCC_CODE'})\n",
    "                 .query('OCC_CODE == @occ_code')) # Only select occupations in occ_code\n",
    "    \n",
    "    ## Prepare CPS data 'W_C_gor' and 'X_C_gor'\n",
    "    # Add OCC_CODE column in df_cps_\n",
    "    df_cps_ = (pd.merge(df_cps_, df_cswlk_temp, on='COC_CODE', how='left')\n",
    "               .dropna(subset=['OCC_CODE'])) # Keep only relevant COC_CODE/OCC_CODE in CPS\n",
    "    \n",
    "    # Computing 'W_C_gor' at the region level based on weights\n",
    "    if weights:\n",
    "        # Summing up weights instead of counting for each OCC_CODE\n",
    "        df_gor = (df_cps_.groupby([region_level,'OCC_CODE','DEM_GROUP'])[weights]\n",
    "                  .sum()\n",
    "                  .rename('W_C_gor')\n",
    "                  .reset_index())\n",
    "    else:\n",
    "        df_gor = (df_cps_.groupby([region_level,'OCC_CODE','DEM_GROUP'])['CPSIDP']\n",
    "                  .nunique()\n",
    "                  .rename('W_C_gor')\n",
    "                  .reset_index())  \n",
    "        \n",
    "    # Compute 'X_C_gor' at the region level\n",
    "    df_gor['X_C_gor'] = df_gor['W_C_gor'] / df_gor.groupby([region_level,'OCC_CODE'])['W_C_gor'].transform('sum')\n",
    "    \n",
    "    ## Add W_C_gor data to dfC (dataframe with all possible STATES x DEM_GROUP)\n",
    "    shape_check = dfC.shape[0]\n",
    "    dfC = pd.merge(dfC, df_gor, on=[region_level, 'OCC_CODE', 'DEM_GROUP'], how='left')\n",
    "    assert shape_check == dfC.shape[0]\n",
    "\n",
    "    return dfC\n",
    "\n",
    "# BLS-OEWS and CPS-based data (dfBC)\n",
    "def prep_dfBC(dfB, dfC):\n",
    "    \"\"\"Prepares BLS-OEWS based dataframe with crossproduct of state, occupations, and demographics\n",
    "        Parameters:\n",
    "        - dfB (pd.DataFrame) : BLS-OEWS dataframe containing 'W_B_os'\n",
    "        - dfC (pd.DataFrame) : CPS dataframe containing 'X_C_gor'\n",
    "        Returns:\n",
    "        - dfBC (pd.DataFrame) : BLS-OEWS and CPS dataframe with 'W_BC_gos'\"\"\"    \n",
    "    \n",
    "    # Merge 'W_B_os' from dfB onto dfC\n",
    "    dfBC = pd.merge(dfC, dfB[['STATE','OCC_CODE','W_B_os']], on=['STATE','OCC_CODE'], how='left', validate='many_to_one')\n",
    "    dfBC['W_BC_gos'] = dfBC['W_B_os'] * dfBC['X_C_gor']\n",
    "\n",
    "    return dfBC\n",
    "\n",
    "def get_W_S_gost(dfA, dfBC, region_level):\n",
    "    \"\"\"Computes 'W_S_gost' from 'X_A_gst' and 'W_BC_gos' for each occupation and state\n",
    "        Parameters:\n",
    "        - dfA : ACS dataframe containing 'X_A_gst'\n",
    "        - dfBC (pd.DataFrame) : BLS-OEWS and CPS dataframe containing 'W_BC_gos'\n",
    "        - region_level (str) : STATE, REGION, DIVISION, NATION\n",
    "        Returns:\n",
    "        - dfS (pd.DataFrame) : result dataframe with 'W_S_gost'\n",
    "    \"\"\" \n",
    "    # Merge 'W_BC_gos' on selected occupation(s), states, and demographic groups\n",
    "    shape_check = dfA.shape[0]\n",
    "    dfS = pd.merge(dfA, dfBC, on=['STATE','DEM_GROUP'], how='left')\n",
    "    assert shape_check == dfS.shape[0]\n",
    "    \n",
    "    # Computing 'W_S_gost'\n",
    "    dfS['W_S_gost'] = dfS['W_BC_gos'] * dfS['X_A_gst']\n",
    "    \n",
    "    return dfS\n",
    "\n",
    "def get_W_S_ost(dfS):\n",
    "    \"\"\"Computes W_S_ost from W_S_gost by combining demographic groups\n",
    "        Parameters:\n",
    "        - dfS (pd.DataFrame) : pd.DataFrame containing 'W_S_gost'\n",
    "        Returns:\n",
    "        - dfS (pd.DataFrame) : pd.DataFrame with 'W_S_ost'\"\"\"\n",
    "    # Combines W_S_gost for all demographic groups for each OxSxT\n",
    "    dfS = (dfS\n",
    "           .groupby(['GEOID','STATE','OCC_CODE','OCC_TITLE'])\n",
    "           .agg({\n",
    "               'W_B_os':np.mean,\n",
    "               'W_S_gost':np.sum,\n",
    "           })\n",
    "           .reset_index()\n",
    "           .rename(columns={\n",
    "               'W_S_gost':'W_S_ost'\n",
    "           }))\n",
    "    \n",
    "    return dfS\n",
    "\n",
    "# Full method\n",
    "#@time_it\n",
    "def run_full_method(region_level, occ_code, occ_level, weights='ASECWT', combine_dem=True, \n",
    "                    display_full=False, folder_df=None, dfA=None, df_bls_=None, \n",
    "                    df_cps_=None, df_cswlk_=None, df_geo_level_=None):\n",
    "    \"\"\"Downscale occupations using the base method\n",
    "        Parameters:\n",
    "        - region_level (str) : STATE, REGION, DIVISION, NATION\n",
    "        - occ_code (str) : specific occupation code to compute 'W_S_gost'\n",
    "        - occ_level (str) : 'major' or 'detailed'\n",
    "        - weights (str) : if 'ASECWT', use weights column to get number of workers (set None for no weights)\n",
    "        - combine_dem (bool) : If True, combine demographic info to return 'W_S_ost' instead of 'W_S_gost'\n",
    "        - display_full (bool) : display heads of all computed dataframes (dfB, dfC, dfBC, dfS)\n",
    "        - folder_df (str) : folder to save results (None : no saving)\n",
    "        - dfA (pd.DataFrame) : common dfA_base dataframe with GEOID x DEM_GROUP data from ACS to save computation time (default: dfA_base)\n",
    "        - df_bls_ (pd.DataFrame) : BLS-OEWS dataframe (default: DF_BLS)\n",
    "        - df_cps_ (pd.DataFrame) : CPS raw data to count workers (default: DF_CPS)\n",
    "        - df_cswlk_ (pd.DataFrame) : crosswalk between SOC and COC codes (default: DF_CSWLK)\n",
    "        - df_geo_level_ (pd.DataFrame) : dataframe with geographic information (default: DF_GEO_LEVEL)\n",
    "        Returns:\n",
    "        - dfS : final base method dataframe with 'W_S_gost' or 'W_S_ost'\"\"\"\n",
    "    \n",
    "    # Loading defaults \n",
    "    if dfA is None:\n",
    "        dfA = dfA_base.copy()\n",
    "    if df_bls_ is None:\n",
    "        df_bls_ = DF_BLS.copy()\n",
    "    if df_cps_ is None:\n",
    "        df_cps_ = DF_CPS.copy()\n",
    "    if df_cswlk_ is None:\n",
    "        df_cswlk_ = DF_CSWLK.copy()\n",
    "    if df_geo_level_ is None:\n",
    "        df_geo_level_ = DF_GEO_LEVEL.copy()\n",
    "        \n",
    "    # dfB with 'W_B_os'\n",
    "    dfB = prep_dfB(occ_level=occ_level, df_bls_=df_bls_)\n",
    "    \n",
    "    # dfC with 'X_C_gor'\n",
    "    dfC = prep_dfC(region_level=region_level, occ_code=occ_code, occ_level=occ_level, weights=weights,\n",
    "                   df_geo_level_=df_geo_level_.copy(), df_cps_=df_cps_.copy(), df_cswlk_=df_cswlk_.copy())\n",
    "    assert dfC['OCC_CODE'].nunique() == 1 # confirm single occupation\n",
    "    \n",
    "    # dfBC with 'W_BC_gos'\n",
    "    shape_check = dfC.shape[0]\n",
    "    dfBC = prep_dfBC(dfB=dfB, dfC=dfC)\n",
    "    assert shape_check == dfBC.shape[0] # both are cross products of SxOxG\n",
    "\n",
    "    ## Results dataframe from dfS_base\n",
    "    dfS = get_W_S_gost(dfA=dfA, dfBC=dfBC, region_level=region_level)\n",
    "    \n",
    "    # Fixing column order\n",
    "    if region_level=='STATE':\n",
    "        col_order = ['OCC_CODE','OCC_TITLE','STATE','GEOID','DEM_GROUP','W_A_gst','X_A_gst','W_C_gor','X_C_gor','W_B_os','W_BC_gos','W_S_gost']\n",
    "    else:\n",
    "        col_order = ['OCC_CODE','OCC_TITLE',region_level,'STATE','GEOID','DEM_GROUP','W_A_gst','X_A_gst','W_C_gor','X_C_gor','W_B_os','W_BC_gos','W_S_gost']\n",
    "    dfS = dfS[col_order]\n",
    "\n",
    "    # Display all dataframes\n",
    "    if display_full:\n",
    "        print(\"dfB\")\n",
    "        display(dfB.head())\n",
    "        print(\"dfC\")\n",
    "        display(dfC.head())\n",
    "        print(\"dfBC\")\n",
    "        display(dfBC.head())\n",
    "        print(\"dfS with W_S_gost\")\n",
    "        display(dfS.head())\n",
    "        \n",
    "    # Combining demographic levels for occupation and tract\n",
    "    if combine_dem:\n",
    "        dfS = dfS.pipe(get_W_S_ost)\n",
    "    \n",
    "    # Display all dataframes\n",
    "    if display_full:\n",
    "        print(\"dfS with W_S_ost\")\n",
    "        display(dfS.head())\n",
    "        \n",
    "    # Save file\n",
    "    if folder_df:\n",
    "        fn = os.path.join(folder_df, f\"{occ_code}_FULL_{region_level}.csv\")\n",
    "        dfS.drop(columns=['OCC_CODE','OCC_TITLE']).round(round_).to_csv(fn, index=False)\n",
    "\n",
    "    return dfS"
   ]
  },
  {
   "cell_type": "markdown",
   "id": "e48ff159",
   "metadata": {},
   "source": [
    "## Example"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 9,
   "id": "4932f92c",
   "metadata": {
    "ExecuteTime": {
     "end_time": "2024-02-13T22:02:22.073013Z",
     "start_time": "2024-02-13T22:02:22.059142Z"
    },
    "scrolled": true
   },
   "outputs": [],
   "source": [
    "# OCC_LEVEL = 'major'\n",
    "# REGION_LEVEL = 'DIVISION'\n",
    "# occ_code = '11-0000'\n",
    "\n",
    "# df = run_full_method(occ_level=OCC_LEVEL, region_level=REGION_LEVEL, occ_code=occ_code, \n",
    "#                        display_full=False, combine_dem=True)\n",
    "# df.head()"
   ]
  },
  {
   "cell_type": "markdown",
   "id": "1c22cad9",
   "metadata": {},
   "source": [
    "# All Methods"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 10,
   "id": "46904323",
   "metadata": {
    "ExecuteTime": {
     "end_time": "2024-02-13T22:02:22.089102Z",
     "start_time": "2024-02-13T22:02:22.075020Z"
    },
    "code_folding": [
     2
    ]
   },
   "outputs": [],
   "source": [
    "## Combined for single occ at a time for all methods\n",
    "@time_it\n",
    "def get_all_methods(occ_code, occ_level, folder_df=None, folder_base=None, folder_full=None):\n",
    "    \"\"\"Returns a dataframe for the base method and 4 region methods for the given occ\n",
    "        Parameters:\n",
    "        - occ_code (str) : specific occupation code to compute 'W_S_gost'\n",
    "        - occ_level (str) : 'major' or 'detailed'\n",
    "        - folder_df (str) : folder to save combined results (None : no saving)\n",
    "        - folder_base (str) : folder to save base method results (None : no saving)\n",
    "        - folder_full (str) : folder to save full method results (None : no saving)\n",
    "        - global vars : LIST_GEO_LEVELS\n",
    "        Returns:\n",
    "        - df_results (pd.DataFrame) : dataframe with tract-level estimates from all 5 methods\"\"\"\n",
    "\n",
    "    ## Base method\n",
    "    df_base = run_base_method(occ_level=occ_level, occ_code=occ_code, folder_df=folder_base)\n",
    "    occ_title = df_base['OCC_TITLE'].unique()[0] # for filename later\n",
    "    \n",
    "    cols_common = ['OCC_CODE','OCC_TITLE','STATE','GEOID']\n",
    "    df_results = (df_base[cols_common + ['W_B_os','W_S1_ost']]\n",
    "                  .rename(columns={\n",
    "                      'W_B_os': 'BLS_EMP_TOT',\n",
    "                      'W_S1_ost': 'EST_BASE'\n",
    "                  }))\n",
    "\n",
    "    ## Full methods\n",
    "    for region_level in LIST_GEO_LEVELS:\n",
    "        # Getting all calculations (for diagnosis)\n",
    "        df_full = run_full_method(region_level=region_level, occ_code=occ_code, occ_level=occ_level, \n",
    "                                  weights='ASECWT', combine_dem=False, folder_df=folder_full)\n",
    "        # Computing 'W_S_ost'\n",
    "        df_full = df_full.pipe(get_W_S_ost)\n",
    " \n",
    "        df_full = (df_full[cols_common + ['W_S_ost']]\n",
    "                   .rename(columns={'W_S_ost': f'EST_FULL_{region_level}'}))\n",
    "        \n",
    "        df_results = pd.merge(df_results, df_full, on=cols_common)\n",
    "\n",
    "    # Replace 0 with np.nan for easier detection of missing data\n",
    "    # Problem is that this cannot detect whether BLS data is 0 or whether ACS is 0\n",
    "    df_results = df_results.replace(0, np.nan)\n",
    "\n",
    "    if folder_df:\n",
    "        fn = os.path.join(folder_df, f\"EST_{occ_code}_{occ_title.replace('/', '--')}.csv\")\n",
    "        df_results.round(round_).to_csv(fn, index=False)\n",
    "        \n",
    "    return df_results"
   ]
  },
  {
   "cell_type": "markdown",
   "id": "dc679297",
   "metadata": {},
   "source": [
    "## Run all and save"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 11,
   "id": "633d0c38",
   "metadata": {
    "ExecuteTime": {
     "end_time": "2024-02-13T22:02:22.120327Z",
     "start_time": "2024-02-13T22:02:22.093204Z"
    },
    "code_folding": [
     0,
     44
    ]
   },
   "outputs": [],
   "source": [
    "def run_parallel(occ_level, folder_df=None, max_workers=64):\n",
    "    \"\"\"Runs parallel computing for all four estimation methods for the given occupation level\n",
    "        Parameters:\n",
    "        - occ_level (str) : 'major' or 'detailed'\n",
    "        - folder_df (str) : folder to save all dataframes; automatically creates a subfolder for df (default: FOLDER_RESULTS)\n",
    "        - max_workers (int) : maximum number of threads to use\n",
    "        Returns:\n",
    "        - dict_results (dict) : a dictionary of estimation dataframes {OCC_CODE:result}\"\"\"\n",
    "    \n",
    "    from concurrent.futures import ThreadPoolExecutor, ProcessPoolExecutor, as_completed\n",
    "    \n",
    "    # Loading defaults\n",
    "    if folder_df is None:\n",
    "        folder_df = FOLDER_RESULTS\n",
    "    \n",
    "    dict_results = {}\n",
    "    list_occ = get_list_occ(occ_level=occ_level)\n",
    "\n",
    "    folder_est = os.path.join(folder_df, occ_level)\n",
    "    if not os.path.exists(folder_est):\n",
    "        os.makedirs(folder_est)\n",
    "            \n",
    "    # Use ProcessPoolExecutor to run tasks in parallel\n",
    "    with ThreadPoolExecutor(max_workers=max_workers) as executor:\n",
    "        # Create a dictionary to map futures to their parameters\n",
    "        future_to_param = {executor.submit(\n",
    "            get_all_methods, occ_code=occ_code, occ_level=occ_level, folder_df=folder_est\n",
    "        ): occ_code for occ_code in list_occ}\n",
    "\n",
    "        # Collect results as they complete\n",
    "        for future in as_completed(future_to_param):\n",
    "            param = future_to_param[future]\n",
    "            try:\n",
    "                result = future.result()\n",
    "                dict_results[param] = future.result()\n",
    "            except Exception as exc:\n",
    "                print(f\"Generated an exception: {exc}\")\n",
    "\n",
    "    # Pickle the combined dataframe\n",
    "    df_results = pd.concat(dict_results.values(), ignore_index=True)\n",
    "    df_results.to_pickle(os.path.join(folder_df, f'df_results_{occ_level}.pkl'))\n",
    "    \n",
    "    return dict_results   \n",
    "\n",
    "def run_serial(occ_level, folder_df=None):\n",
    "    \"\"\"Runs sequential computing for  all four estimation methods for the given occupation level\n",
    "        Parameters:\n",
    "        - occ_level (str) : 'major' or 'detailed'\n",
    "        - folder_df (str) : folder to save all dataframes; automatically creates a subfolder for df (default: FOLDER_RESULTS)\n",
    "        Returns:\n",
    "        - dict_results (dict) : a dictionary of estimation dataframes {OCC_CODE:result}\"\"\"\n",
    "    \n",
    "    # Loading defaults\n",
    "    if folder_df is None:\n",
    "        folder_df = FOLDER_RESULTS\n",
    "    \n",
    "    dict_results = {}\n",
    "    list_occ = get_list_occ(occ_level=occ_level)\n",
    "\n",
    "    folder_est = os.path.join(folder_df, occ_level)\n",
    "    if not os.path.exists(folder_est):\n",
    "        os.makedirs(folder_est)\n",
    "\n",
    "    for occ_code in list_occ:\n",
    "        dict_results[occ_code] = get_all_methods(occ_code=occ_code, occ_level=occ_level, folder_df=folder_est)\n",
    "\n",
    "    # Pickle the combined dataframe            \n",
    "    df_results = pd.concat(dict_results.values(), ignore_index=True)\n",
    "    df_results.to_pickle(os.path.join(folder_df, f'df_results_{occ_level}.pkl'))\n",
    "    \n",
    "    return dict_results"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "id": "7ec5de04",
   "metadata": {
    "ExecuteTime": {
     "end_time": "2024-02-08T06:21:38.073757Z",
     "start_time": "2024-02-08T06:19:26.650182Z"
    }
   },
   "outputs": [],
   "source": [
    "# Parallel - major\n",
    "dict_results_major = run_parallel(occ_level='major')"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "id": "410f8a3a",
   "metadata": {
    "ExecuteTime": {
     "end_time": "2024-02-08T07:40:46.127396Z",
     "start_time": "2024-02-08T06:21:38.075758Z"
    }
   },
   "outputs": [],
   "source": [
    "# Parallel - detailed\n",
    "dict_results_detailed = run_parallel(occ_level='detailed')"
   ]
  },
  {
   "cell_type": "markdown",
   "id": "bd51b107",
   "metadata": {},
   "source": [
    "# RMSE for Major Occupations"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 12,
   "id": "af78b1a7",
   "metadata": {
    "ExecuteTime": {
     "end_time": "2024-02-13T22:02:38.689006Z",
     "start_time": "2024-02-13T22:02:30.220936Z"
    },
    "code_folding": [
     3,
     69,
     89
    ],
    "scrolled": true
   },
   "outputs": [
    {
     "name": "stdout",
     "output_type": "stream",
     "text": [
      "get_X_A_ost took 2.2 seconds\n",
      "get_rmse took 7.4 seconds\n",
      "get_total_emp took 0.0 seconds\n",
      "get_nonzero_dem_groups took 0.6 seconds\n"
     ]
    },
    {
     "data": {
      "text/html": [
       "<div>\n",
       "<style scoped>\n",
       "    .dataframe tbody tr th:only-of-type {\n",
       "        vertical-align: middle;\n",
       "    }\n",
       "\n",
       "    .dataframe tbody tr th {\n",
       "        vertical-align: top;\n",
       "    }\n",
       "\n",
       "    .dataframe thead th {\n",
       "        text-align: right;\n",
       "    }\n",
       "</style>\n",
       "<table border=\"1\" class=\"dataframe\">\n",
       "  <thead>\n",
       "    <tr style=\"text-align: right;\">\n",
       "      <th></th>\n",
       "      <th>OCC_CODE</th>\n",
       "      <th>OCC_TITLE</th>\n",
       "      <th>TOT_EMP</th>\n",
       "      <th>RMSE_EST_BASE</th>\n",
       "      <th>RMSE_EST_FULL_STATE</th>\n",
       "      <th>RMSE_EST_FULL_DIVISION</th>\n",
       "      <th>RMSE_EST_FULL_REGION</th>\n",
       "      <th>RMSE_EST_FULL_NATION</th>\n",
       "      <th>MIN_RMSE</th>\n",
       "      <th>N_DEM_STATE</th>\n",
       "      <th>N_DEM_DIVISION</th>\n",
       "      <th>N_DEM_REGION</th>\n",
       "      <th>N_DEM_NATION</th>\n",
       "    </tr>\n",
       "  </thead>\n",
       "  <tbody>\n",
       "    <tr>\n",
       "      <th>0</th>\n",
       "      <td>11-0000</td>\n",
       "      <td>Management Occupations</td>\n",
       "      <td>7226910.0</td>\n",
       "      <td>0.050552</td>\n",
       "      <td>0.050914</td>\n",
       "      <td>0.051789</td>\n",
       "      <td>0.052797</td>\n",
       "      <td>0.053554</td>\n",
       "      <td>RMSE_EST_BASE</td>\n",
       "      <td>17.831371</td>\n",
       "      <td>24.869034</td>\n",
       "      <td>28.284678</td>\n",
       "      <td>32.0</td>\n",
       "    </tr>\n",
       "    <tr>\n",
       "      <th>1</th>\n",
       "      <td>13-0000</td>\n",
       "      <td>Business and Financial Operations Occupations</td>\n",
       "      <td>7431560.0</td>\n",
       "      <td>0.069719</td>\n",
       "      <td>0.072513</td>\n",
       "      <td>0.071475</td>\n",
       "      <td>0.072218</td>\n",
       "      <td>0.072652</td>\n",
       "      <td>RMSE_EST_BASE</td>\n",
       "      <td>14.974841</td>\n",
       "      <td>21.481830</td>\n",
       "      <td>25.927652</td>\n",
       "      <td>32.0</td>\n",
       "    </tr>\n",
       "    <tr>\n",
       "      <th>2</th>\n",
       "      <td>15-0000</td>\n",
       "      <td>Computer and Mathematical Occupations</td>\n",
       "      <td>4246060.0</td>\n",
       "      <td>0.112734</td>\n",
       "      <td>0.110133</td>\n",
       "      <td>0.108897</td>\n",
       "      <td>0.108325</td>\n",
       "      <td>0.107937</td>\n",
       "      <td>RMSE_EST_FULL_NATION</td>\n",
       "      <td>14.360763</td>\n",
       "      <td>21.453790</td>\n",
       "      <td>25.459111</td>\n",
       "      <td>31.0</td>\n",
       "    </tr>\n",
       "    <tr>\n",
       "      <th>3</th>\n",
       "      <td>17-0000</td>\n",
       "      <td>Architecture and Engineering Occupations</td>\n",
       "      <td>2499600.0</td>\n",
       "      <td>0.103132</td>\n",
       "      <td>0.104911</td>\n",
       "      <td>0.104537</td>\n",
       "      <td>0.105647</td>\n",
       "      <td>0.105448</td>\n",
       "      <td>RMSE_EST_BASE</td>\n",
       "      <td>10.566558</td>\n",
       "      <td>17.032673</td>\n",
       "      <td>20.709780</td>\n",
       "      <td>30.0</td>\n",
       "    </tr>\n",
       "    <tr>\n",
       "      <th>4</th>\n",
       "      <td>19-0000</td>\n",
       "      <td>Life, Physical, and Social Science Occupations</td>\n",
       "      <td>1136150.0</td>\n",
       "      <td>0.139022</td>\n",
       "      <td>0.140934</td>\n",
       "      <td>0.138331</td>\n",
       "      <td>0.137368</td>\n",
       "      <td>0.137169</td>\n",
       "      <td>RMSE_EST_FULL_NATION</td>\n",
       "      <td>8.517866</td>\n",
       "      <td>15.925942</td>\n",
       "      <td>20.329303</td>\n",
       "      <td>28.0</td>\n",
       "    </tr>\n",
       "    <tr>\n",
       "      <th>5</th>\n",
       "      <td>21-0000</td>\n",
       "      <td>Community and Social Service Occupations</td>\n",
       "      <td>2079060.0</td>\n",
       "      <td>0.083675</td>\n",
       "      <td>0.086032</td>\n",
       "      <td>0.086311</td>\n",
       "      <td>0.087925</td>\n",
       "      <td>0.089989</td>\n",
       "      <td>RMSE_EST_BASE</td>\n",
       "      <td>12.245209</td>\n",
       "      <td>19.997601</td>\n",
       "      <td>23.872991</td>\n",
       "      <td>32.0</td>\n",
       "    </tr>\n",
       "    <tr>\n",
       "      <th>6</th>\n",
       "      <td>23-0000</td>\n",
       "      <td>Legal Occupations</td>\n",
       "      <td>1089870.0</td>\n",
       "      <td>0.141965</td>\n",
       "      <td>0.142986</td>\n",
       "      <td>0.141960</td>\n",
       "      <td>0.141468</td>\n",
       "      <td>0.141633</td>\n",
       "      <td>RMSE_EST_FULL_REGION</td>\n",
       "      <td>7.107599</td>\n",
       "      <td>12.253329</td>\n",
       "      <td>15.958835</td>\n",
       "      <td>20.0</td>\n",
       "    </tr>\n",
       "    <tr>\n",
       "      <th>7</th>\n",
       "      <td>25-0000</td>\n",
       "      <td>Education, Training, and Library Occupations</td>\n",
       "      <td>8662680.0</td>\n",
       "      <td>0.057400</td>\n",
       "      <td>0.059646</td>\n",
       "      <td>0.059688</td>\n",
       "      <td>0.060438</td>\n",
       "      <td>0.062662</td>\n",
       "      <td>RMSE_EST_BASE</td>\n",
       "      <td>18.117635</td>\n",
       "      <td>26.058273</td>\n",
       "      <td>28.927624</td>\n",
       "      <td>32.0</td>\n",
       "    </tr>\n",
       "    <tr>\n",
       "      <th>8</th>\n",
       "      <td>27-0000</td>\n",
       "      <td>Arts, Design, Entertainment, Sports, and Media...</td>\n",
       "      <td>1912520.0</td>\n",
       "      <td>0.102251</td>\n",
       "      <td>0.105326</td>\n",
       "      <td>0.104462</td>\n",
       "      <td>0.103728</td>\n",
       "      <td>0.103406</td>\n",
       "      <td>RMSE_EST_BASE</td>\n",
       "      <td>11.418512</td>\n",
       "      <td>18.123177</td>\n",
       "      <td>21.694174</td>\n",
       "      <td>28.0</td>\n",
       "    </tr>\n",
       "    <tr>\n",
       "      <th>9</th>\n",
       "      <td>29-0000</td>\n",
       "      <td>Healthcare Practitioners and Technical Occupat...</td>\n",
       "      <td>8458580.0</td>\n",
       "      <td>0.061486</td>\n",
       "      <td>0.061641</td>\n",
       "      <td>0.063129</td>\n",
       "      <td>0.065139</td>\n",
       "      <td>0.066477</td>\n",
       "      <td>RMSE_EST_BASE</td>\n",
       "      <td>16.531156</td>\n",
       "      <td>24.123921</td>\n",
       "      <td>27.458532</td>\n",
       "      <td>30.0</td>\n",
       "    </tr>\n",
       "    <tr>\n",
       "      <th>10</th>\n",
       "      <td>31-0000</td>\n",
       "      <td>Healthcare Support Occupations</td>\n",
       "      <td>4084840.0</td>\n",
       "      <td>0.085083</td>\n",
       "      <td>0.079502</td>\n",
       "      <td>0.084938</td>\n",
       "      <td>0.087750</td>\n",
       "      <td>0.092010</td>\n",
       "      <td>RMSE_EST_FULL_STATE</td>\n",
       "      <td>12.992514</td>\n",
       "      <td>21.651341</td>\n",
       "      <td>26.039028</td>\n",
       "      <td>30.0</td>\n",
       "    </tr>\n",
       "    <tr>\n",
       "      <th>11</th>\n",
       "      <td>33-0000</td>\n",
       "      <td>Protective Service Occupations</td>\n",
       "      <td>3380660.0</td>\n",
       "      <td>0.093862</td>\n",
       "      <td>0.092801</td>\n",
       "      <td>0.096171</td>\n",
       "      <td>0.097794</td>\n",
       "      <td>0.099759</td>\n",
       "      <td>RMSE_EST_FULL_STATE</td>\n",
       "      <td>12.724710</td>\n",
       "      <td>21.116670</td>\n",
       "      <td>24.339312</td>\n",
       "      <td>29.0</td>\n",
       "    </tr>\n",
       "    <tr>\n",
       "      <th>12</th>\n",
       "      <td>35-0000</td>\n",
       "      <td>Food Preparation and Serving Related Occupations</td>\n",
       "      <td>13082920.0</td>\n",
       "      <td>0.070377</td>\n",
       "      <td>0.067512</td>\n",
       "      <td>0.069849</td>\n",
       "      <td>0.070578</td>\n",
       "      <td>0.073327</td>\n",
       "      <td>RMSE_EST_FULL_STATE</td>\n",
       "      <td>19.485304</td>\n",
       "      <td>27.737462</td>\n",
       "      <td>30.127037</td>\n",
       "      <td>32.0</td>\n",
       "    </tr>\n",
       "    <tr>\n",
       "      <th>13</th>\n",
       "      <td>37-0000</td>\n",
       "      <td>Building and Grounds Cleaning and Maintenance ...</td>\n",
       "      <td>4377790.0</td>\n",
       "      <td>0.087349</td>\n",
       "      <td>0.084301</td>\n",
       "      <td>0.086721</td>\n",
       "      <td>0.087489</td>\n",
       "      <td>0.090011</td>\n",
       "      <td>RMSE_EST_FULL_STATE</td>\n",
       "      <td>16.207491</td>\n",
       "      <td>25.059252</td>\n",
       "      <td>28.567137</td>\n",
       "      <td>31.0</td>\n",
       "    </tr>\n",
       "    <tr>\n",
       "      <th>14</th>\n",
       "      <td>39-0000</td>\n",
       "      <td>Personal Care and Service Occupations</td>\n",
       "      <td>5125170.0</td>\n",
       "      <td>0.076056</td>\n",
       "      <td>0.075589</td>\n",
       "      <td>0.076446</td>\n",
       "      <td>0.078258</td>\n",
       "      <td>0.080826</td>\n",
       "      <td>RMSE_EST_FULL_STATE</td>\n",
       "      <td>16.605614</td>\n",
       "      <td>25.582812</td>\n",
       "      <td>29.155450</td>\n",
       "      <td>31.0</td>\n",
       "    </tr>\n",
       "    <tr>\n",
       "      <th>15</th>\n",
       "      <td>41-0000</td>\n",
       "      <td>Sales and Related Occupations</td>\n",
       "      <td>14434710.0</td>\n",
       "      <td>0.040877</td>\n",
       "      <td>0.044085</td>\n",
       "      <td>0.046824</td>\n",
       "      <td>0.048850</td>\n",
       "      <td>0.051367</td>\n",
       "      <td>RMSE_EST_BASE</td>\n",
       "      <td>21.390830</td>\n",
       "      <td>28.241997</td>\n",
       "      <td>29.733174</td>\n",
       "      <td>32.0</td>\n",
       "    </tr>\n",
       "    <tr>\n",
       "      <th>16</th>\n",
       "      <td>43-0000</td>\n",
       "      <td>Office and Administrative Support Occupations</td>\n",
       "      <td>21824260.0</td>\n",
       "      <td>0.038410</td>\n",
       "      <td>0.040220</td>\n",
       "      <td>0.043817</td>\n",
       "      <td>0.045791</td>\n",
       "      <td>0.049089</td>\n",
       "      <td>RMSE_EST_BASE</td>\n",
       "      <td>22.296438</td>\n",
       "      <td>28.404946</td>\n",
       "      <td>31.176046</td>\n",
       "      <td>32.0</td>\n",
       "    </tr>\n",
       "    <tr>\n",
       "      <th>17</th>\n",
       "      <td>45-0000</td>\n",
       "      <td>Farming, Fishing, and Forestry Occupations</td>\n",
       "      <td>469750.0</td>\n",
       "      <td>0.240314</td>\n",
       "      <td>0.210488</td>\n",
       "      <td>0.240263</td>\n",
       "      <td>0.239994</td>\n",
       "      <td>0.240409</td>\n",
       "      <td>RMSE_EST_FULL_STATE</td>\n",
       "      <td>6.578511</td>\n",
       "      <td>12.733050</td>\n",
       "      <td>16.123687</td>\n",
       "      <td>23.0</td>\n",
       "    </tr>\n",
       "    <tr>\n",
       "      <th>18</th>\n",
       "      <td>47-0000</td>\n",
       "      <td>Construction and Extraction Occupations</td>\n",
       "      <td>5677030.0</td>\n",
       "      <td>0.078288</td>\n",
       "      <td>0.076516</td>\n",
       "      <td>0.080513</td>\n",
       "      <td>0.081536</td>\n",
       "      <td>0.082249</td>\n",
       "      <td>RMSE_EST_FULL_STATE</td>\n",
       "      <td>10.756348</td>\n",
       "      <td>16.511649</td>\n",
       "      <td>20.525945</td>\n",
       "      <td>27.0</td>\n",
       "    </tr>\n",
       "    <tr>\n",
       "      <th>19</th>\n",
       "      <td>49-0000</td>\n",
       "      <td>Installation, Maintenance, and Repair Occupations</td>\n",
       "      <td>5485710.0</td>\n",
       "      <td>0.084548</td>\n",
       "      <td>0.081873</td>\n",
       "      <td>0.087548</td>\n",
       "      <td>0.087924</td>\n",
       "      <td>0.088713</td>\n",
       "      <td>RMSE_EST_FULL_STATE</td>\n",
       "      <td>10.486586</td>\n",
       "      <td>16.653547</td>\n",
       "      <td>20.701991</td>\n",
       "      <td>28.0</td>\n",
       "    </tr>\n",
       "    <tr>\n",
       "      <th>20</th>\n",
       "      <td>51-0000</td>\n",
       "      <td>Production Occupations</td>\n",
       "      <td>8998460.0</td>\n",
       "      <td>0.085701</td>\n",
       "      <td>0.084209</td>\n",
       "      <td>0.087433</td>\n",
       "      <td>0.088476</td>\n",
       "      <td>0.090066</td>\n",
       "      <td>RMSE_EST_FULL_STATE</td>\n",
       "      <td>17.694643</td>\n",
       "      <td>26.197510</td>\n",
       "      <td>29.978825</td>\n",
       "      <td>32.0</td>\n",
       "    </tr>\n",
       "    <tr>\n",
       "      <th>21</th>\n",
       "      <td>53-0000</td>\n",
       "      <td>Transportation and Material Moving Occupations</td>\n",
       "      <td>9913910.0</td>\n",
       "      <td>0.063638</td>\n",
       "      <td>0.058670</td>\n",
       "      <td>0.065367</td>\n",
       "      <td>0.066996</td>\n",
       "      <td>0.070318</td>\n",
       "      <td>RMSE_EST_FULL_STATE</td>\n",
       "      <td>19.169994</td>\n",
       "      <td>26.205754</td>\n",
       "      <td>28.940404</td>\n",
       "      <td>32.0</td>\n",
       "    </tr>\n",
       "  </tbody>\n",
       "</table>\n",
       "</div>"
      ],
      "text/plain": [
       "   OCC_CODE                                          OCC_TITLE     TOT_EMP  \\\n",
       "0   11-0000                             Management Occupations   7226910.0   \n",
       "1   13-0000      Business and Financial Operations Occupations   7431560.0   \n",
       "2   15-0000              Computer and Mathematical Occupations   4246060.0   \n",
       "3   17-0000           Architecture and Engineering Occupations   2499600.0   \n",
       "4   19-0000     Life, Physical, and Social Science Occupations   1136150.0   \n",
       "5   21-0000           Community and Social Service Occupations   2079060.0   \n",
       "6   23-0000                                  Legal Occupations   1089870.0   \n",
       "7   25-0000       Education, Training, and Library Occupations   8662680.0   \n",
       "8   27-0000  Arts, Design, Entertainment, Sports, and Media...   1912520.0   \n",
       "9   29-0000  Healthcare Practitioners and Technical Occupat...   8458580.0   \n",
       "10  31-0000                     Healthcare Support Occupations   4084840.0   \n",
       "11  33-0000                     Protective Service Occupations   3380660.0   \n",
       "12  35-0000   Food Preparation and Serving Related Occupations  13082920.0   \n",
       "13  37-0000  Building and Grounds Cleaning and Maintenance ...   4377790.0   \n",
       "14  39-0000              Personal Care and Service Occupations   5125170.0   \n",
       "15  41-0000                      Sales and Related Occupations  14434710.0   \n",
       "16  43-0000      Office and Administrative Support Occupations  21824260.0   \n",
       "17  45-0000         Farming, Fishing, and Forestry Occupations    469750.0   \n",
       "18  47-0000            Construction and Extraction Occupations   5677030.0   \n",
       "19  49-0000  Installation, Maintenance, and Repair Occupations   5485710.0   \n",
       "20  51-0000                             Production Occupations   8998460.0   \n",
       "21  53-0000     Transportation and Material Moving Occupations   9913910.0   \n",
       "\n",
       "    RMSE_EST_BASE  RMSE_EST_FULL_STATE  RMSE_EST_FULL_DIVISION  \\\n",
       "0        0.050552             0.050914                0.051789   \n",
       "1        0.069719             0.072513                0.071475   \n",
       "2        0.112734             0.110133                0.108897   \n",
       "3        0.103132             0.104911                0.104537   \n",
       "4        0.139022             0.140934                0.138331   \n",
       "5        0.083675             0.086032                0.086311   \n",
       "6        0.141965             0.142986                0.141960   \n",
       "7        0.057400             0.059646                0.059688   \n",
       "8        0.102251             0.105326                0.104462   \n",
       "9        0.061486             0.061641                0.063129   \n",
       "10       0.085083             0.079502                0.084938   \n",
       "11       0.093862             0.092801                0.096171   \n",
       "12       0.070377             0.067512                0.069849   \n",
       "13       0.087349             0.084301                0.086721   \n",
       "14       0.076056             0.075589                0.076446   \n",
       "15       0.040877             0.044085                0.046824   \n",
       "16       0.038410             0.040220                0.043817   \n",
       "17       0.240314             0.210488                0.240263   \n",
       "18       0.078288             0.076516                0.080513   \n",
       "19       0.084548             0.081873                0.087548   \n",
       "20       0.085701             0.084209                0.087433   \n",
       "21       0.063638             0.058670                0.065367   \n",
       "\n",
       "    RMSE_EST_FULL_REGION  RMSE_EST_FULL_NATION              MIN_RMSE  \\\n",
       "0               0.052797              0.053554         RMSE_EST_BASE   \n",
       "1               0.072218              0.072652         RMSE_EST_BASE   \n",
       "2               0.108325              0.107937  RMSE_EST_FULL_NATION   \n",
       "3               0.105647              0.105448         RMSE_EST_BASE   \n",
       "4               0.137368              0.137169  RMSE_EST_FULL_NATION   \n",
       "5               0.087925              0.089989         RMSE_EST_BASE   \n",
       "6               0.141468              0.141633  RMSE_EST_FULL_REGION   \n",
       "7               0.060438              0.062662         RMSE_EST_BASE   \n",
       "8               0.103728              0.103406         RMSE_EST_BASE   \n",
       "9               0.065139              0.066477         RMSE_EST_BASE   \n",
       "10              0.087750              0.092010   RMSE_EST_FULL_STATE   \n",
       "11              0.097794              0.099759   RMSE_EST_FULL_STATE   \n",
       "12              0.070578              0.073327   RMSE_EST_FULL_STATE   \n",
       "13              0.087489              0.090011   RMSE_EST_FULL_STATE   \n",
       "14              0.078258              0.080826   RMSE_EST_FULL_STATE   \n",
       "15              0.048850              0.051367         RMSE_EST_BASE   \n",
       "16              0.045791              0.049089         RMSE_EST_BASE   \n",
       "17              0.239994              0.240409   RMSE_EST_FULL_STATE   \n",
       "18              0.081536              0.082249   RMSE_EST_FULL_STATE   \n",
       "19              0.087924              0.088713   RMSE_EST_FULL_STATE   \n",
       "20              0.088476              0.090066   RMSE_EST_FULL_STATE   \n",
       "21              0.066996              0.070318   RMSE_EST_FULL_STATE   \n",
       "\n",
       "    N_DEM_STATE  N_DEM_DIVISION  N_DEM_REGION  N_DEM_NATION  \n",
       "0     17.831371       24.869034     28.284678          32.0  \n",
       "1     14.974841       21.481830     25.927652          32.0  \n",
       "2     14.360763       21.453790     25.459111          31.0  \n",
       "3     10.566558       17.032673     20.709780          30.0  \n",
       "4      8.517866       15.925942     20.329303          28.0  \n",
       "5     12.245209       19.997601     23.872991          32.0  \n",
       "6      7.107599       12.253329     15.958835          20.0  \n",
       "7     18.117635       26.058273     28.927624          32.0  \n",
       "8     11.418512       18.123177     21.694174          28.0  \n",
       "9     16.531156       24.123921     27.458532          30.0  \n",
       "10    12.992514       21.651341     26.039028          30.0  \n",
       "11    12.724710       21.116670     24.339312          29.0  \n",
       "12    19.485304       27.737462     30.127037          32.0  \n",
       "13    16.207491       25.059252     28.567137          31.0  \n",
       "14    16.605614       25.582812     29.155450          31.0  \n",
       "15    21.390830       28.241997     29.733174          32.0  \n",
       "16    22.296438       28.404946     31.176046          32.0  \n",
       "17     6.578511       12.733050     16.123687          23.0  \n",
       "18    10.756348       16.511649     20.525945          27.0  \n",
       "19    10.486586       16.653547     20.701991          28.0  \n",
       "20    17.694643       26.197510     29.978825          32.0  \n",
       "21    19.169994       26.205754     28.940404          32.0  "
      ]
     },
     "metadata": {},
     "output_type": "display_data"
    }
   ],
   "source": [
    "#For RMSE, we need X_A_ost and X_S_ost for each geographic level\n",
    "# Requires dataframe with estimated data (df_results_major)\n",
    "@time_it\n",
    "def get_X_A_ost(df_acs_emp_=None):\n",
    "    \"\"\"Returns tract-to-state worker proportion by occupation (X_A_ost) from the ACS Employment data\n",
    "        Parameters:\n",
    "        - df_acs_emp_ (pd.DataFrame) : ACS employment dataframe (default: DF_ACS_EMP)\n",
    "        - DICT_ACS_EMP_COLS (global var) : dict of {OCC_TITLE:[OCC_COLS]}\n",
    "        Returns:\n",
    "        - df (pd.DataFrame) : Dataframe with GEOID, STATE, OCC_TITLE, W_A_ost, X_A_ost\"\"\"\n",
    "    \n",
    "    # Loading defaults\n",
    "    if df_acs_emp_ is None:\n",
    "        df = DF_ACS_EMP.copy()\n",
    "    else:\n",
    "        df = df_acs_emp_.copy()\n",
    "        \n",
    "    for occ_title, acs_occ_codes in DICT_ACS_EMP_COLS.items():\n",
    "        df[occ_title] = df[acs_occ_codes].sum(axis=1)\n",
    "\n",
    "    # Get tract-level worker count\n",
    "    df = df.melt(id_vars=['GEOID','STATE'], value_vars=DICT_ACS_EMP_COLS.keys(), var_name='OCC_TITLE', value_name='W_A_ost')\n",
    "    # Compute tract-to-state worker proportions\n",
    "    df['X_A_ost'] = df['W_A_ost'] / df.groupby(['STATE','OCC_TITLE'])['W_A_ost'].transform('sum')\n",
    "\n",
    "    df = df.pipe(add_occ_details, add_occ_code=True)\n",
    "    \n",
    "    return df\n",
    "\n",
    "@time_it\n",
    "def get_rmse(df_est, dfA_ost=None):\n",
    "    \"\"\"Returns RMSE for each major occupation\n",
    "        Parameters:\n",
    "        - df_est (pd.DataFrame) : Dataframe with estimated W_S_ost for each region_level\n",
    "        - dfA_ost (pd.DataFrame) : Dataframe with ACS X_A_ost\n",
    "        Returns:\n",
    "        - df (pd.DataFrame) : Dataframe with RMSE for each major occupation\"\"\"\n",
    "    \n",
    "    # Loading defaults\n",
    "    if dfA_ost is None:\n",
    "        dfA_ost = get_X_A_ost()\n",
    "        \n",
    "    shape_check = dfA_ost.shape[0]\n",
    "    df = pd.merge(df_est, dfA_ost, on=['OCC_CODE','OCC_TITLE','STATE','GEOID'])\n",
    "    assert shape_check == df.shape[0]\n",
    "    \n",
    "    # Creating dataframe with OCC_CODEs\n",
    "    df_rmse = dfA_ost[['OCC_CODE']].drop_duplicates().reset_index(drop=True)\n",
    "    \n",
    "    # Merging ACS and Estimated data\n",
    "    df_merged = pd.merge(df_results_major, dfA_ost, on=['OCC_CODE','OCC_TITLE','STATE','GEOID'])\n",
    "\n",
    "    est_cols = [col for col in df_merged.columns if col[0:4]=='EST_']\n",
    "    X_est_cols = [f'X_S_ost_{col}' for col in est_cols]\n",
    "    # Computing X_S_ost\n",
    "    df_merged[X_est_cols] = df_merged[est_cols] / df_merged.groupby(['STATE','OCC_CODE'])[est_cols].transform('sum')\n",
    "\n",
    "    for est_col in est_cols:\n",
    "        df = (df_merged.groupby('OCC_CODE')\n",
    "              .apply(compute_rmse, col1=f'X_S_ost_{est_col}', col2='X_A_ost')\n",
    "              .rename(f'RMSE_{est_col}')\n",
    "              .reset_index())\n",
    "        df_rmse = pd.merge(df_rmse, df, on=['OCC_CODE'])\n",
    "    \n",
    "    df_rmse['MIN_RMSE'] = df_rmse[[col for col in df_rmse.columns if col[:4]=='RMSE']].idxmin(axis=1)\n",
    "        \n",
    "    return df_rmse\n",
    "\n",
    "@time_it\n",
    "def get_total_emp(dfB=None):\n",
    "    \"\"\"Returns total employment for each major occupation\n",
    "        Parameters:\n",
    "        - dfB (pd.DataFrame) :  : BLS-OEWS dataframe containing 'W_B_os'\n",
    "        Returns:\n",
    "        - df (pd.DataFrame) : Dataframe with TOT_EMP for each major occupation\"\"\"\n",
    "    # Loading defaults\n",
    "    if dfB is None:\n",
    "        dfB = prep_dfB(occ_level='major')\n",
    "\n",
    "    # BLS total employment by occupation\n",
    "    df = (dfB\n",
    "          .groupby('OCC_CODE')['W_B_os'].sum()\n",
    "          .reset_index()\n",
    "          .rename(columns={'W_B_os':'TOT_EMP'})\n",
    "          .pipe(add_occ_details))\n",
    "    \n",
    "    return df\n",
    "\n",
    "@time_it\n",
    "def get_nonzero_dem_groups(occ_level, df_cps_=None, df_cswlk_=None, df_acs_emp_=None, df_geo_level_=None, fn=None):\n",
    "    \"\"\"Returns a dataframe with non-zero demographic groups for every full estimation method for all major occupations\n",
    "        Parameters:\n",
    "        - occ_level (str) : 'major' or 'detailed'\n",
    "        - df_cps_ (pd.DataFrame) : CPS raw data to count workers (default: DF_CPS)\n",
    "        - df_acs_emp_ (pd.DataFrame) : ACS employment dataframe (default: DF_ACS_EMP)\n",
    "        - df_geo_level_ (pd.DataFrame) : dataframe with geographic information (default: DF_GEO_LEVEL)\n",
    "        - df_cswlk_ (pd.DataFrame) : crosswalk between SOC and COC codes (default: DF_CSWLK)\n",
    "        - fn (str) : filename to save the dataframe (.csv)\n",
    "        Returns:\n",
    "        - df (pd.DataFrame) : Dataframe with number of non-zero demographic groups\"\"\"\n",
    "    # Loading defaults\n",
    "    if df_cps_ is None:\n",
    "        df_cps_ = DF_CPS.copy()\n",
    "    if df_cswlk_ is None:\n",
    "        df_cswlk_ = DF_CSWLK.copy()\n",
    "    if df_acs_emp_ is None:\n",
    "        df_acs_emp_ = DF_ACS_EMP.copy()\n",
    "    if df_geo_level_ is None:\n",
    "        df_geo_level_ = DF_GEO_LEVEL.copy()\n",
    "\n",
    "    col_occ_code = 'SOC_CODE_MAJOR' if occ_level=='major' else 'SOC_CODE' if occ_level=='detailed' else np.nan\n",
    "    df_cswlk_ = df_cswlk_[['COC_CODE',col_occ_code]]\n",
    "    df_acs_emp_ = df_acs_emp_[['STATE','GEOID']]\n",
    "    \n",
    "    num_tracts = df_acs_emp_['GEOID'].nunique() # total number of tracts\n",
    "    \n",
    "    # Adding geographic levels to get unique demographic group counts\n",
    "    df_acs_emp_ = pd.merge(df_acs_emp_, df_geo_level_, on='STATE')\n",
    "    df_cps_ = pd.merge(df_cps_, df_cswlk_, on='COC_CODE', how='right')\n",
    "    df_cps_ = df_cps_.rename(columns={col_occ_code: 'OCC_CODE'})\n",
    "    \n",
    "    # Base dataframe with all occupations\n",
    "    df = (df_cps_[['OCC_CODE']]\n",
    "          .drop_duplicates()\n",
    "          .reset_index(drop=True)\n",
    "          .sort_values(by='OCC_CODE'))\n",
    "\n",
    "    # Merging number of non-zero demographic groups for each geographic level -- weighted by number of tracts\n",
    "    for geo_level in LIST_GEO_LEVELS:\n",
    "        # Unique DEM_GROUP counts per geographic level\n",
    "        df_dem = (df_cps_\n",
    "                  .groupby(['OCC_CODE',geo_level])['DEM_GROUP']\n",
    "                  .nunique()\n",
    "                  .reset_index())\n",
    "        # Number of tracts per geographic level\n",
    "        df_tracts = (df_acs_emp_.groupby(geo_level)['GEOID']\n",
    "                     .count()\n",
    "                     .reset_index())\n",
    "        # Weighted (tracts) number of unique DEM_GROUPS per geographic level\n",
    "        df_ = pd.merge(df_dem, df_tracts, on=geo_level)\n",
    "        df_[f'N_DEM_{geo_level}'] = df_['GEOID'] * df_['DEM_GROUP']\n",
    "        df_ = df_.groupby('OCC_CODE')[f'N_DEM_{geo_level}'].sum() / num_tracts\n",
    "        \n",
    "        df = pd.merge(df, df_, on='OCC_CODE')\n",
    "\n",
    "    return df\n",
    "\n",
    "## RMSE\n",
    "# df_results_major = pd.concat(dict_results_major.values(), ignore_index=True)\n",
    "df_results_major = pd.read_pickle(os.path.join(FOLDER_RESULTS, \"df_results_major.pkl\"))\n",
    "df_rmse = get_rmse(df_est=df_results_major.copy())\n",
    "\n",
    "## TOT_EMP\n",
    "df_tot_emp = get_total_emp()\n",
    "\n",
    "## Non-zero demographic groups\n",
    "df_dem_groups = get_nonzero_dem_groups(occ_level='major')\n",
    "\n",
    "## Combine diagnostics\n",
    "df_diag = pd.merge(df_tot_emp, df_rmse, on=['OCC_CODE'])\n",
    "df_diag = pd.merge(df_diag, df_dem_groups, on=['OCC_CODE'])\n",
    "df_diag.round(round_).to_csv(os.path.join(FOLDER_RESULTS, \"performance_metrics.csv\"), index=False)\n",
    "display(df_diag)"
   ]
  },
  {
   "cell_type": "markdown",
   "id": "e00dc03b",
   "metadata": {},
   "source": [
    "# Generate Summary"
   ]
  },
  {
   "cell_type": "markdown",
   "id": "5f0123d8",
   "metadata": {},
   "source": [
    "- '29-1024' has 0 workers in the BLS data"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 13,
   "id": "a9413970",
   "metadata": {
    "ExecuteTime": {
     "end_time": "2024-02-13T22:03:03.084300Z",
     "start_time": "2024-02-13T22:02:50.153621Z"
    }
   },
   "outputs": [],
   "source": [
    "# Read all data\n",
    "df_detailed = pd.read_pickle(os.path.join(FOLDER_RESULTS, 'df_results_detailed.pkl'))"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "id": "3d35df64",
   "metadata": {
    "ExecuteTime": {
     "end_time": "2024-02-13T00:56:38.275186Z",
     "start_time": "2024-02-13T00:56:26.407765Z"
    },
    "code_folding": [
     0
    ]
   },
   "outputs": [],
   "source": [
    "def generate_summary_detailed(df_detailed, df_bls_=None, fn=None):\n",
    "    \"\"\"Returns a summary of downscaled detailed occupations\n",
    "        Parameters:\n",
    "        - df_detailed (pd.DataFrame) : dataframe with OCC x TRACT estimates of all methods\n",
    "        - fn (str) : filename to save the summary (.excel)\n",
    "        Returns:\n",
    "        - df (pd.DataFrame) : Dataframe with occupation, estimates, number of tracts, % of tracts\"\"\"\n",
    "    # Loading defaults\n",
    "    if df_bls_ is None:\n",
    "        df_bls_ = DF_BLS[DF_BLS['OCC_GROUP']=='detailed'].copy()\n",
    "    \n",
    "    # Summary of downscaled data\n",
    "    cols_est = [col for col in df_detailed.columns if col[:4] == 'EST_']\n",
    "    cols_tracts = [col.replace('EST_', 'TRACTS_') for col in cols_est]\n",
    "\n",
    "    # Compute number of tracts with downscaled data\n",
    "    df = (df_detailed.groupby(['OCC_CODE','OCC_TITLE'])[cols_est]\n",
    "                  .count()\n",
    "                  .reset_index()\n",
    "                  .rename(columns={k:v for k, v in zip(cols_est, cols_tracts)}))\n",
    "\n",
    "    # Add TOT_EMP from BLS data\n",
    "    df_bls_ = df_bls_.groupby(['OCC_CODE','OCC_TITLE'])['TOT_EMP'].sum()\n",
    "    df = pd.merge(df_bls_, df, on=['OCC_CODE','OCC_TITLE'])\n",
    "    df = df.replace(0, np.nan)\n",
    "\n",
    "    # Indicator for each tract\n",
    "    df[cols_est] = df[cols_tracts].notna().astype(int)\n",
    "\n",
    "    # Percentage\n",
    "    cols_pct_tracts =  [col.replace('TRACTS_', 'PCT_TRACTS_') for col in cols_tracts]\n",
    "    df[cols_pct_tracts] = (df[cols_est].sum() / df[cols_est].count())\n",
    "    df[cols_pct_tracts] = df[cols_pct_tracts].applymap(lambda x: \"{:.1%}\".format(x))\n",
    "\n",
    "    cols_order = ['OCC_CODE','OCC_TITLE','TOT_EMP'] + cols_est + cols_tracts + cols_pct_tracts\n",
    "    df = df[cols_order]\n",
    "    \n",
    "    if fn:\n",
    "        df.to_excel(fn, index=False)\n",
    "    \n",
    "    return df\n",
    "\n",
    "df_summary = generate_summary_detailed(df_detailed, fn=os.path.join(FOLDER_RESULTS, \"SUMMARY_TABLE.xlsx\"))"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 36,
   "id": "79f50a8c",
   "metadata": {
    "ExecuteTime": {
     "end_time": "2024-02-13T03:17:24.008675Z",
     "start_time": "2024-02-13T03:17:23.995669Z"
    }
   },
   "outputs": [
    {
     "data": {
      "text/html": [
       "<div>\n",
       "<style scoped>\n",
       "    .dataframe tbody tr th:only-of-type {\n",
       "        vertical-align: middle;\n",
       "    }\n",
       "\n",
       "    .dataframe tbody tr th {\n",
       "        vertical-align: top;\n",
       "    }\n",
       "\n",
       "    .dataframe thead th {\n",
       "        text-align: right;\n",
       "    }\n",
       "</style>\n",
       "<table border=\"1\" class=\"dataframe\">\n",
       "  <thead>\n",
       "    <tr style=\"text-align: right;\">\n",
       "      <th></th>\n",
       "      <th>OCC_CODE</th>\n",
       "      <th>OCC_TITLE</th>\n",
       "      <th>STATE</th>\n",
       "      <th>GEOID</th>\n",
       "      <th>BLS_EMP_TOT</th>\n",
       "      <th>EST_BASE</th>\n",
       "      <th>EST_FULL_STATE</th>\n",
       "      <th>EST_FULL_DIVISION</th>\n",
       "      <th>EST_FULL_REGION</th>\n",
       "      <th>EST_FULL_NATION</th>\n",
       "    </tr>\n",
       "  </thead>\n",
       "  <tbody>\n",
       "    <tr>\n",
       "      <th>0</th>\n",
       "      <td>13-1041</td>\n",
       "      <td>Compliance Officers</td>\n",
       "      <td>Alabama</td>\n",
       "      <td>14000US01001020100</td>\n",
       "      <td>1460.0</td>\n",
       "      <td>0.662692</td>\n",
       "      <td>0.813053</td>\n",
       "      <td>0.804420</td>\n",
       "      <td>0.682048</td>\n",
       "      <td>0.639794</td>\n",
       "    </tr>\n",
       "    <tr>\n",
       "      <th>1</th>\n",
       "      <td>13-1041</td>\n",
       "      <td>Compliance Officers</td>\n",
       "      <td>Alabama</td>\n",
       "      <td>14000US01001020200</td>\n",
       "      <td>1460.0</td>\n",
       "      <td>0.503284</td>\n",
       "      <td>0.299668</td>\n",
       "      <td>0.390216</td>\n",
       "      <td>0.476144</td>\n",
       "      <td>0.427260</td>\n",
       "    </tr>\n",
       "    <tr>\n",
       "      <th>2</th>\n",
       "      <td>13-1041</td>\n",
       "      <td>Compliance Officers</td>\n",
       "      <td>Alabama</td>\n",
       "      <td>14000US01001020300</td>\n",
       "      <td>1460.0</td>\n",
       "      <td>1.202174</td>\n",
       "      <td>0.977987</td>\n",
       "      <td>1.080972</td>\n",
       "      <td>1.055990</td>\n",
       "      <td>1.019005</td>\n",
       "    </tr>\n",
       "    <tr>\n",
       "      <th>3</th>\n",
       "      <td>13-1041</td>\n",
       "      <td>Compliance Officers</td>\n",
       "      <td>Alabama</td>\n",
       "      <td>14000US01001020400</td>\n",
       "      <td>1460.0</td>\n",
       "      <td>1.200782</td>\n",
       "      <td>1.196350</td>\n",
       "      <td>1.423628</td>\n",
       "      <td>1.274686</td>\n",
       "      <td>1.181094</td>\n",
       "    </tr>\n",
       "    <tr>\n",
       "      <th>4</th>\n",
       "      <td>13-1041</td>\n",
       "      <td>Compliance Officers</td>\n",
       "      <td>Alabama</td>\n",
       "      <td>14000US01001020500</td>\n",
       "      <td>1460.0</td>\n",
       "      <td>3.612786</td>\n",
       "      <td>4.030422</td>\n",
       "      <td>3.099368</td>\n",
       "      <td>3.331516</td>\n",
       "      <td>3.549117</td>\n",
       "    </tr>\n",
       "  </tbody>\n",
       "</table>\n",
       "</div>"
      ],
      "text/plain": [
       "  OCC_CODE            OCC_TITLE    STATE               GEOID  BLS_EMP_TOT  \\\n",
       "0  13-1041  Compliance Officers  Alabama  14000US01001020100       1460.0   \n",
       "1  13-1041  Compliance Officers  Alabama  14000US01001020200       1460.0   \n",
       "2  13-1041  Compliance Officers  Alabama  14000US01001020300       1460.0   \n",
       "3  13-1041  Compliance Officers  Alabama  14000US01001020400       1460.0   \n",
       "4  13-1041  Compliance Officers  Alabama  14000US01001020500       1460.0   \n",
       "\n",
       "   EST_BASE  EST_FULL_STATE  EST_FULL_DIVISION  EST_FULL_REGION  \\\n",
       "0  0.662692        0.813053           0.804420         0.682048   \n",
       "1  0.503284        0.299668           0.390216         0.476144   \n",
       "2  1.202174        0.977987           1.080972         1.055990   \n",
       "3  1.200782        1.196350           1.423628         1.274686   \n",
       "4  3.612786        4.030422           3.099368         3.331516   \n",
       "\n",
       "   EST_FULL_NATION  \n",
       "0         0.639794  \n",
       "1         0.427260  \n",
       "2         1.019005  \n",
       "3         1.181094  \n",
       "4         3.549117  "
      ]
     },
     "execution_count": 36,
     "metadata": {},
     "output_type": "execute_result"
    }
   ],
   "source": [
    "df_detailed.head()"
   ]
  },
  {
   "cell_type": "markdown",
   "id": "85da8ddd",
   "metadata": {},
   "source": [
    "# Plots"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 15,
   "id": "80f9e432",
   "metadata": {
    "ExecuteTime": {
     "end_time": "2024-02-13T22:30:41.314631Z",
     "start_time": "2024-02-13T22:30:37.331622Z"
    }
   },
   "outputs": [
    {
     "name": "stderr",
     "output_type": "stream",
     "text": [
      "C:\\Users\\agrawa3\\AppData\\Roaming\\Python\\Python39\\site-packages\\matplotlib\\projections\\__init__.py:63: UserWarning: Unable to import Axes3D. This may be due to multiple versions of Matplotlib being installed (e.g. as a system package and as a pip package). As a result, the 3D projection is not available.\n",
      "  warnings.warn(\"Unable to import Axes3D. This may be due to multiple versions of \"\n"
     ]
    }
   ],
   "source": [
    "import matplotlib as mpl\n",
    "import matplotlib.pyplot as plt\n",
    "\n",
    "import seaborn as sns\n",
    "sns.set(font_scale=1.2)\n",
    "sns.set_style(\"white\")\n",
    "\n",
    "figsize = (10, 8)\n",
    "fontsize_axis = 18\n",
    "fontsize_title = 16\n",
    "dpi = 1200\n",
    "\n",
    "font = {'family' : 'serif',\n",
    "        'weight' : 'normal',\n",
    "        'size'   : 12}\n",
    "mpl.rc('font', **font)\n",
    "\n",
    "grid_lw = 0.5\n",
    "grid_alpha = 0.5\n",
    "grid_color = \"grey\"\n",
    "\n",
    "dict_markers = {\n",
    "    'BASE': '*',\n",
    "    'STATE': 'o',\n",
    "    'DIVISION': 's',\n",
    "    'REGION': 'D',\n",
    "    'NATION': 'P'\n",
    "}\n",
    "\n",
    "dict_colors = {\n",
    "    'BASE': 'green',\n",
    "    'STATE': 'red',\n",
    "    'DIVISION': 'orange',\n",
    "    'REGION': 'blue',\n",
    "    'NATION': 'purple'\n",
    "}"
   ]
  },
  {
   "cell_type": "markdown",
   "id": "d081e8da",
   "metadata": {},
   "source": [
    "## RMSEs (Major Occupation) vs. Non-zero Demographic Groups (GEO_LEVEL)"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 18,
   "id": "dddbce4a",
   "metadata": {
    "ExecuteTime": {
     "end_time": "2024-02-13T22:33:29.712484Z",
     "start_time": "2024-02-13T22:33:27.132374Z"
    }
   },
   "outputs": [
    {
     "data": {
      "image/png": "iVBORw0KGgoAAAANSUhEUgAAAn4AAAHpCAYAAAAcWzEGAAAAOXRFWHRTb2Z0d2FyZQBNYXRwbG90bGliIHZlcnNpb24zLjguMiwgaHR0cHM6Ly9tYXRwbG90bGliLm9yZy8g+/7EAAAACXBIWXMAAAsTAAALEwEAmpwYAADUMklEQVR4nOydd3hURffHP+khhV4MIASUHUtAEVABRZoKqChWEBBeVLCg8vITsRfsBQXFhtKl2AAboFIiKoRmAXxhQCAYmnRIgSSE/f0xu0sSUnaT3b27yfk8zz7JnTs799zvzu6ePTNzJsRutyMIgiAIgiBUfEKtNkAQBEEQBEHwD+L4CYIgCIIgVBLE8RMEQRAEQagkiOMnCIIgCIJQSQi32oBARykVBbQBdgN5FpsjCIIgCIJQEmFAArBKa51d+KQ4fqXTBvjZaiMEQRAEQRA84HLgl8KF4viVzm6A6dOnc8YZZ1htiyAIgiAIQrHs2bOHvn37gsN/KYw4fqWTB3DGGWfQsGFDq22xlNTUVBITE602w1JEA4PoYBAdRAMnooNo4CSAdChyepos7hDcJjU11WoTLEc0MIgOBtFBNHAiOogGTgJdB3H8BEEQBEEQKgni+AmCIAiCIFQSxPET3KZVq1ZWm2A5ooFBdDCIDqKBE9FBNHAS6DrI4g5BEARBCCAOHjzIzp07ycnJsdoUIQCJjIykQYMG1KxZs0zPF8dPcJs1a9bQsWNHq82wFNHAIDoYRAfRwIm3dDh48CBpaWmcddZZxMTEEBoqA3PCKU6ePElWVhZbtmwBKJPzJz1KEARBEAKEnTt3ctZZZxEXFydOn3AaoaGhxMXFcdZZZ7Fz586yteFlmwRBEARBKCM5OTnExMRYbYYQ4MTExJR5KoA4foLbBEhCSksRDQyig0F0EA2ceFMHifQJpVGePiK9S3Ab+YAXDZyIDgbRQTRwIjoIwYIlizuUUsOAO4AcIA0YorU+WES9esAIoI2jKBYYq7Welq/OQGAYcDjfU3/UWr+Yr86FwLuY7UuqAI9qrRd5634qC8uWLaNdu3ZWm2EpooFBdDCIDqKBE9FBCBb8HvFTSt0CDAc6a60vBfYC04qpfgtwLtBVa30FcA8wQSnVrVC9YVrrjvke+Z2+eGA+MFpr3QG4H5irlGrs3Tur+EhqAdHAiehgEB1EAyf+0CE3N5fJkyfTp08f+vfvT58+fbjpppt47rnnWL58uc+v728OHjxI//79ad68ObNnzy62Xk5ODh07duT7778v87XmzZvHrbfeilKK66+/no8//rjMbZUHd++5PFgR8RsOTNNaH3YcvwNsUEoprbUuVPcvYI3WOhdAa71aKbUOuAZY4Ob1bgfytNazHW2sVEr9hXEiHyvfrQiCIAiC78nJyeHOO++katWqfPjhh1StWhWA3bt3M3ToUH744Qd+/fVXi630LjVr1mTatGl07ty5xHphYWE0adKEWrVqlflaPXr0oEWLFnTp0oXHH3+cSy65pMxtlQd377k8+NXxU0pFAK2BsfmKNZANtHP8f+qE1kuKaCYG+LdQ2V1KqWcx95MCPKe1TnecawesL1T/T0e54AFxcXFWm2A5ooFBdDCIDqKBE1/r8M4777B161Z+/PHHAqt+ExISePnll/nPf/7j0+sHMmFhYUyaNMlqM4IGf0f86jiuechZoLW2K6UOA2eU9mSlVHOgHvBRvuI9wBJgEhAJzAS+U0pdobW2AwnAgUJNHXLnevlJSUmhdu3awKntWNasWeM6n5iYSGJiIsuWLXOF/OPi4mjdujVaa3bv3u2q27ZtW9LT01m//pQ/arPZqF+/PsnJya6yWrVq0bx5c9atW8eBA6duoWPHjuzatYtNmza5ypKSkoiPjy8Q7k9ISEApxerVq8nIyABMxu927dqRmppKamqqq66797R69eoKd0+evk5AhbsnT1+njIwMV/2Kck9lfZ2ACndPnrxOrVu3rnD3VNbXKTk5udz3FB8fT2Hy8vKYOXMmPXr0KDLVi81mY8SIEQXKli9fzpgxYwgJCQHgsssu45577iE83HztHz9+nDfeeIOUlBSio6MJDw/n//7v/2jTpo2rjbVr1/Lss8+Sl5dH7dq16datG08++SQXXHABDz30ED///DM//PADDRo0oEuXLvzyyy+sXbuWzp078/LLL/PSSy/x22+/ERMTw7Fjx7j99tu58cYbAZg7dy6TJk1i48aNvPXWW3z22WccOHCA6OhoRo0axbnnnlvgfg4dOsTIkSPZvn07x48f55VXXuGcc84BoH///mzYsIEBAwbwwAMPACbR8XvvvceCBQuoWrUqWVlZtG3blvvuu69IjT2hOG13797N/fffj9aaCy64gKeffpqkpCQeeeQRFi5cyAUXXMCkSZPIy8vjnXfeYfHixa7I7QMPPFCmKGP+fubseykpKSU/yW63++1hs9nq22w2u81mu7pQ+R6bzfZYKc+Nttlsv9pstp6l1DvHcY1LHMc/2Gy2mYXqvGKz2bSbNifabDZ7WlqavbKzceNGq02wHNHAIDoYRAfRwIm3dFi9evVpZZs2bbLbbDb7lClT3Gpj69at9ubNm7vaysjIsF9//fX2t956y1Xn0Ucftd922232Y8eO2e12u/3HH3+0JyUl2bdv3+56zqWXXup6Tm5urv2ee+6xF/4+fPvtt+0XXnihff78+Xa73W5ftWqV/amnnrLn5ubaL7vsMvuhQ4fsdrvdvnfvXnv79u3tq1atcj03JSXFbrPZ7E899ZT95MmTdrvdbn/ttdfsl112mcsuu91u79Spk71Xr1729PR0u91ut7/wwgv2fv36Fbjnfv362d9+++0Cdl111VX2gwcP2u12u33Xrl32iy++2P6///2vWN3S0tLsNpvNnpKSUmZtjxw5Ym/evLl97ty5ruekp6fbe/XqVcC2Xr162TMzM12anX/++fYtW7YUuOcvv/yyWDvs9qL7Sv77sNlsifYi/Bp/L+7YD5wAajgLlFIhQHVM5K5IHEPEM4DxWuuvS7nGNsffpo6/e/Jfz0GNkq4nFE3+X7qVFdHAIDoYRAfRwIkvdTh69CgAVapUcav++PHjOf/8810RzdjYWK677jqmTTPrKHfs2MGcOXMYMGAA0dHRAHTt2pVGjRrxwQcfAPDdd99x8OBBBg4cCEB4eDj9+/cv8nrVq1enWzez5rJ169aMGjWK8PBwPv30U6pXrw5AnTp1uPjii/npp59Oe/6gQYNc0bO77rqLvXv38s033xSo07lzZ9dw+qWXXsqGDRuKvf/s7Gw+/vhjbr31VmrUMF//CQkJDBs2jGrVqpUsXimUpm3VqlXp2rUrc+bMcT1n3rx59OjRo4Btffr0cUVvW7duTWJiIjNmzCiXbe7i16FerXWOUmoNkJSv2AZEAUUuSXI4fbOAb7XWUxxlzbXW6xz/j9Za/1++pyQ4/qY5/i4DnijUbAvg9N4nCIIgCAGGczgwKyurQPnhw4d54IEHOHHiBP/++y9vvvkmF154IVpr9uzZU8BRy8zMpFq1ahw5coRNmzZht9tPyz3YuHFjNm7cCMDff/9N1apVXY4bQP369Yu074wzip45tXr1ambPnk12djbh4eFs3bqVDh06nFavQYMGrv9r1KhBfHw8f//9d4E69erVc/0fFxdHeno6xZGamsrx48dp3Lhg8o4+ffoU+xx3KU3batWq0atXL+6++2527txJgwYN+OqrrxgzZkwB26ZNm8bXX5+KY504ceK019dXWLGq903gNaXU61rrI8BQYJ7WeqNS6jxgAjBIa73B4fR9CvwCfKaUcs6efQfo6Pj/RqXUAq31j47o4UhgHbDCcX4G8KxS6gat9VylVBuM49nbD/cqCIIgCOWiadOmVK1atcBcQDCRtmnTprFjxw66dOlCdna269wFF1zA+++/7xf7nPMG8/P9998zYsQIJkyYwGWXXQbAo48+it1uP62uM9pXEmFhYeU31EuUpm379u2pV68ec+bMoUePHsTHx1OnTp0CdR544AGuvPJKX5taJH7P46e1/gwYAyxRSqVgFlk4XedqmLx9VR3HDwG9gNFAer5Hfp4CnlRKJWNW9NYErsmXAuYo0A14WCm1FHgPuEFrvd0X91eRadu2rdUmWI5oYBAdDKKDaODElzqEhYXRp08fFi5cWGKky4lSiq1btxYoO3jwIE899RRgFgGEhISwfXvBr8Ht27e7FkycffbZHD16lMOHD7vO79q1y22bV65cSfXq1V1OH5g8hEWxc+fOAnamp6dz9tlnu32twiQmJhIdHX3a/X333Xds3ry5TG3+97//BUrXFsx2atdffz1z585l9uzZrgUt+W0r3Mb8+fNPG972FZZs2aa1HqO1vkhrfanW+hbnrh1a6+Va6+pa6xWO4ze01iFFPDrma+sTrfUVjsTNl2itb9NapxW63h9a68u01h201m1k146y4c4HTkVHNDCIDgbRQTRw4msdhg4dis1mY9iwYRw8eGqjq5ycHJYuXQqc2r918ODB7Ny50+VI2O123nnnHdd8t4YNG9KrVy+mTJnC8ePHAVi0aBH//PMPQ4YMAeCaa66hZs2aTJ48GTAriz///HO37T377LM5cuQI69atA8yq3JUrVxZZd/r06a5I4IQJE6hbty7XXXed29cqTFRUFHfffTefffYZhw6ZJCJpaWmMHj26zLn+/vzzT6B0bZ306tWLtLQ0vvnmGzp16nSabZ9++il79+4FYP/+/YwdO9aVNcLXWLJlmxCcrF+/no4dO1pthqWIBgbRwSA6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DYDY2FiaNGlCeLj7A5aJiYlUq1bNrbplaT/Y8OudKaUigNbA2HzFGsgG2jn+P3VC6yVFNBMD/Os4nw28Udz5fJyjlPoWMxS8F3hRa72mbHchCIIgCIKvqV27NmPGjOGmm25ixIgRzJo1i7POOovJkyd71M5bb73ldt2ytB9s+NulreO45iFngdbarpQ6DJxR2pOVUs2BesBHxZwPAW4GXit06i/gYa31IaXUbcAypVRLrfX/3DU8JSWF2rVrA9CqVSsA1qw55TsmJiaSmJjIsmXLyMnJASAuLo7WrVujtWb37t2uum3btiU9PZ3169e7ymw2G/Xr1yc5OdlVVqtWLZo3b866des4cOCAq7xjx47s2rWLTZs2ucqSkpKIj49n+fLlrrKEhASUUqxevdqVYyoyMpJ27dqRmppaYGjCnXvKzs5m9erVFeqewLPXqWHDhgAV6p7K8jplZ2e76leUeyrL62S32wEq1D15+jq1atWqwt1TWV4n53uivPcUHx+PpSxoA8f3nl4eXRe6rfK7OREREfTt25enn36a1atXM3bsWFauXMnUqVOJjIxk5MiR7Ny5k4suuoiPPvqIrKws7r//fjZt2sSQIUPQWpOSksLll1/OK6+8AsCvv/7K2LFjiYqKIicnh+bNmzN8+HDS0tJ44YUXXO1fcsklAOzfv58XX3yRLVu2ANC0aVOefPJJateuzdatW3nmmWdYuXIlzz//PL/88gupqanUqVOH0aNHU716dZ/qk7+fOfteSkpKyU+y2+1+e9hstvo2m81us9muLlS+x2azPVbKc6NtNtuvNputZwl1/muz2T5zw44Um832vps2J9psNntaWpq9snP06FGrTbAc0cAgOhhEB9HAibd0WL16tVfaKTNzGtnt81ud/pjTyOeX7tSpk/3tt98+rXz9+vV2m81m/+STT+x2u91us9nsKSkpBc5t3rzZVX/JkiX21157zXU8cuRI+8iRI+12u92em5trv+iii+zLli2z2+12+7Fjx+xXX311ge/4/O3b7Xb7bbfdZn/00Uddx48++qi9d+/eBWy02Wz2IUOG2HNzc+0nTpyw33jjjfaxY8eWWQt3KK6vpKWl2R2+VqK9CL/G33P89gMngBrOAkeUrjqwp7gnOYaIZwDjtdZfF1OnN9CZUyt8S2Ib0NRtqwWg4K/iyopoYBAdDKKDaOBE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\n",
      "text/plain": [
       "<Figure size 720x576 with 1 Axes>"
      ]
     },
     "metadata": {
      "needs_background": "light"
     },
     "output_type": "display_data"
    }
   ],
   "source": [
    "## RMSEs (Major Occupation) vs. Non-zero Demographic Groups (GEO_LEVEL)\n",
    "\n",
    "fig = plt.figure(figsize=figsize)\n",
    "ax = plt.gca()\n",
    "\n",
    "# Scatter plot\n",
    "for geo_level in LIST_GEO_LEVELS:\n",
    "    # sns.scatterplot(data=df_diag, x=f'N_DEM_{geo_level}', y=f'RMSE_EST_FULL_{geo_level}', ax=ax)\n",
    "    sns.regplot(data=df_diag, x=f'N_DEM_{geo_level}', y=f'RMSE_EST_FULL_{geo_level}', ci=None, scatter=True, \n",
    "                marker=dict_markers[geo_level], color=dict_colors[geo_level], label=geo_level.capitalize(), ax=ax)\n",
    "\n",
    "# Grid and labels\n",
    "ax.grid(which=\"major\", axis=\"both\", color=\"gray\", alpha=0.5, ls=\"--\")\n",
    "ax.set_xlim(0,34)\n",
    "ax.set_xticks(np.arange(0, 33, 4))\n",
    "ax.set_ylim(0,0.260)\n",
    "ax.set_yticks(np.arange(0, 0.26, 0.025))\n",
    "ax.set_xlabel(\"Number of Average Non-zero Demographic Groups\")\n",
    "ax.set_ylabel(\"Root Mean Square Error (RMSE)\")\n",
    "\n",
    "# Legend\n",
    "ax.legend(title='Geographic Level', ncol=1, fontsize=14, bbox_to_anchor=(1, 1), loc='upper right', frameon=True, framealpha=1)\n",
    "        \n",
    "plt.savefig(os.path.join(FOLDER_FIGURES, \"RMSE vs. Dem Groups.jpg\"), dpi=dpi, format='jpg')\n",
    "plt.show()"
   ]
  },
  {
   "cell_type": "markdown",
   "id": "90ef6c4c",
   "metadata": {},
   "source": [
    "## Number of Detailed Occupations vs. Non-zero Demographic Groups"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 19,
   "id": "dc740e7b",
   "metadata": {
    "ExecuteTime": {
     "end_time": "2024-02-13T22:34:53.340729Z",
     "start_time": "2024-02-13T22:34:50.252538Z"
    }
   },
   "outputs": [
    {
     "name": "stdout",
     "output_type": "stream",
     "text": [
      "get_nonzero_dem_groups took 0.5 seconds\n"
     ]
    },
    {
     "data": {
      "image/png": "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5vLLL2f16tUMGjSI/fbbj0suuYQddtiBs88+m5deeonnn3+eTTfdlLFjx/Lvf/+bt99+mzFjxnDNNddw9dVX8/rrr7P++uvz9ddfM2HCBA477DAAnnjiCe6++27effddbrrpJh555BEWLVpEUVERV155Jd/+9reb1Wfx4sWcf/75fPTRRyxfvpxrr72WbbcNpoidOHEi77zzDscffzxnnnkmEEyK+/vf/55nn32W/v3789VXXzFq1ChOO+00iouLM/l41qI1t/Pnz+f000/H3dlhhx34xS9+QXl5OT//+c/5+9//zg477MDdd9/N6tWrufXWW3nxxRfjLapnnnlm7lr/YrFYj/kqKysrLSsri82dOzeWDd59992snCefkQM5iMXkIBaTg1hMDmKx5g5mzpy5VnltbW2srKwsdu+996Z1vg8//DA2fPjw+LmWLVsWO+SQQ2I33XRTfJ8LLrggdtRRR8W+/vrrWCwWi73wwgux8vLy2EcffRQ/Zrfddosfs3LlythPfvKTWPLfw9/+9rexHXfcMfbMM8/EYrFY7LXXXotdeumlsZUrV8b22GOP2OLFi2OxWCz26aefxnbffffYa6+9Fj+2uro6VlZWFrv00ktja9asicVisdivf/3r2B577BGPKxaLxfbZZ5/YuHHjYg0NDbFYLBa76qqrYscee2yzOh977LGx3/72t83i+t73vhf7/PPPY7FYLFZfXx/bZZddYv/9739b9TZ37txYWVlZrLq6ut1uv/jii9jw4cNjTzzxRPyYhoaG2Lhx45rFNm7cuNiXX34Zd7bddtvFPvjgg2Z1fuyxx1qNIxZr+V5JrEdZWVlprIW8RgMbOkDiki09FTmQA5ADkAOQA2jbwdKlwbSm6623Xsr9mrjzzjvZbrvt4suK9e3bl4MOOoipU6cCwYz+06ZN4/jjj6eoqAiA7373u2y++ebcfvvtAPztb3/j888/Z9KkSQD07t2biRMntni9DTbYgP322w8IWhWvvPJKevfuzcMPP8wGG2wAwLe+9S122WUX/vnPf651/I9//ON4q9aJJ57Ip59+yl//+tdm+4wZMybe7bzbbrvxzjvvtFr/FStWcNddd3HkkUey4YYbAkG38+TJkxkwYEBqeW3Qltv+/fvz3e9+l2nTpsWPefrpp9l///2bxTZ+/Ph4q+rIkSMpLS3lgQce6FBs6aLuVCGEECJHNHW5ffXVV822L1myhDPPPJNVq1bxySefcOONN7Ljjjvi7ixYsKBZ0vXll18yYMAAvvjiC2pra4nFYmvNT7fFFlvw7rvvAvD+++/Tv3//eBIGMGTIkBbjGzx4cIvbZ86cyeOPP86KFSvo3bs3H374IXvttdda+2266abx1xtuuCHFxcW8//77zfbZZJNN4q/79etHQ0NDi9eEYI3y5cuXs8UWWzTbPn78+FaPSZe23A4YMIBx48Zx0kkn8fHHH7Ppppvyl7/8hZtvvrlZbFOnTuXJJ5+Mn2PVqlVrfb6dhZI4IYQQIkdsueWW9O/fn9ra2mbbN9hgA6ZOnRpfK3PFihXxsh122IE//OEPOYmv6Tm7RJ577jl+9rOfMWXKFPbYYw8ALrjgAmItrL3e1AqXil69enU80CzRltvdd9+dTTbZhGnTprH//vtTXFzMt771rWb7nHnmmey7776dHWqLqDu1A4waNSrqECJHDuQA5ADkAOQA2nbQq1cvxo8fz9///veULVBNmBkffvhhs22ff/45l156KRAMhCgoKOCjjz5qts9HH30UHyyw9dZbs3TpUpYsWRIvr6+vT6c6ALz66qtssMEG8QQOgnnuWuLjjz9uFmdDQwNbb7112tdKprS0lKKiorXq97e//Y333nuvXec855xzgLbdQrAk1iGHHMITTzzB448/Hh/MkRhb8jmeeeaZtbqQOwslcR0gnR/A7o4cyAHIAcgByAGk5+CMM86grKyMyZMn8/nnn8e3NzY28q9//Qv4Zj3Nk08+mY8//jieFMRiMW699db482FDhw5l3Lhx3HvvvSxfvhyA6dOn87///Y9TTjkFgAMOOICNNtqIe+65BwhGyD766KNp12nrrbfmiy++oKamBghGl7766qst7nv//ffHW+imTJnCxhtvzEEHHZT2tZLp06cPJ510Eo888giLFy8GYO7cudxwww3tnkvurbfeAtp228S4ceOYO3cuf/3rX9lnn33Wiu3hhx/m008/BWDhwoXccsstlJWVtSu2TFF3ageYPXs2FRUVUYcRKXIgByAHIAcgB5Ceg8LCQqZMmcL999/PKaecQmFhIStXrmT58uVss8023HHHHfHpQYYNG8Yf//hHbrzxRu6++2769OnDiBEjOOuss+Lnu+yyy7j++us54ogj4lOMTJkyJf4cWd++fbnjjju47LLLePHFFykpKeHggw/m6aefZt111wXgtttuY9q0aSxdupSJEydy/vnnU15eDsCRRx7JBx98wBlnnMGWW27JwIED2XLLLXnppZe4/PLLufzyy+Ox7L777vEBDX369OHOO++kqKgoPsHxZ599xp133gnAoEGDuOGGG4BgapHrrruO888/n3feeYePP/6Yr7/+mp///Oeceuqp8X0GDBjAOuusww033MBGG23Uot+//vWvTJkyBYArrrhirbn7mhKudNw27fed73yH8vLyuK8mTj31VGKxGMcddxwDBw5knXXW4cILL8TM+Pzzzzn77LPjdf7iiy+yPwdgS0NWu+tXtqcY+cc//pGV8+QzciAHsZgcxGJyEIvJQSzW3EFr00ZEwcKFC5u9nzVrVqy8vDy2evXqrJy/aYoR0T40xYgQQgghWmTChAl88sknQNCdev/993PwwQfHu21FfqLu1A6Qqz7vrowcyAHIAcgByAF0XQff//73Ofnkk+nfvz+NjY2Ul5fHH/DvKE0rNkDQ5XnRRRettUqD6BwKYi0MEe6umFkpMGf69OkMHTo06nCEEEJ0Y2bNmhWfSFaIVLR2rzRNOQMMc/e65HK1o3aAysrKqEOIHDmQA5ADkAOQA5ADkVuUxAkhhBBC5CFK4oQQQggh8hAlcR2gvRMNdifkQA5ADkAOQA5ADkRuURLXAYYPHx51CJEjB3IAcgByAHIAciByi5K4DtC0BElPRg7kAOQA5ADkAORA5BbNE9cBFi1aFHUIkSMHcgByAHIAcgA5cLB8ORQVde41OnC91atX88c//pG///3vrLfeeqxatYp11lmHXXfdNb6c1a233sq4ceMynuqrvcd1Z9QSJ4QQQuQLRUVQUJC7rwwTxj/84Q88/fTT3HPPPUydOpUHH3yQI488kttvvz2+z2233cbHH3+ccdXbe1x3RklcZ7B8eW6OEUIIIboQ06dPZ4899mi26PwhhxzC9ttvH2FU3Rd1p3aAioqKlgua/lPKhDxdOaNVBz0IOZADkAOQA5CDddddl9dee40VK1bQp0+f+PaHHnqIzz//nLPPPhuAq6++mv79+7Pzzjtz1lln8corr3DbbbcB0NjYyLBhw7jooovo379/yuMA7r77bp544gmKi4uJxWKcccYZjBo1Ksc1j4acJXFmNgmYDCxJ2PyCu/8qLF8A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3Lhx3HvvvWy22Wb07duXYcOGxddJTYfS0lIGDBiQ1r7tOX++oZY4IYQQQnQqgwYN4uabb6Zfv3787Gc/A2CrrbbinnvuoVevXmmf56abbmLXXXdNa9/2nD/fUBLXATQTtxyAHIAcgByAHIAcpGLdddflmGOO4Y033mDmzJlMnDgRM+OVV17hjTfe4Hvf+x7bbbcdEydOZPny5Xz++eeMHz+eESNGcOedd/LTn/6U3XffnQsuuCB+zpdffpkjjzySiRMnctRRR3HVVVfx1Vdf4e7Nzt/EwoULOeecczj44IM5+OCDmTx5MgsXLgTgww8/jB/zyCOPcNZZZ3HwwQdzwgknsGTJklzrSgslcUIIIYTICeXl5QC4O1OnTo1v32mnnbjppptYtWoVl112GUVFRWy00UaccsopHH300Zx88snccMMN7LnnnvFjVq1axVlnncU555zD1KlTuffee/n3v//N559/jpk1O38TZ5xxBkVFRTz55JM8+eSTrLfeevEu3y233DJ+zIsvvsiNN97ItGnTWLJkCffdd19namk3SuI6wKxZs6IOIXLkQA5ADkAOQA5ADtqiX79+ADQ0NKxVtt1221FWVsa0adPi25544gnGjRvX4rm+/PJLli1bxscffwxAUVERN998M4MGDWpx/+rqat544w1OOumk+LYTTzyR119/vVlrHcB+++1H79696dWrFyNHjuSdd97JrKI5QkmcEEIIIXJCU/LWv3//FssPOeQQ/vrXv7JmzRqWLl3Kp59+ytZbb93ivgMGDOCUU07h0ksv5YgjjuDuu+9m8ODBFBUVtbj/e++9R0FBAZtvvnl82+abb05BQQG1tbXN9t1kk03ir/v27dtll1NTEieEEEKInFBTUwPA9ttv32L5QQcdxMKFC6mqquLpp59mv/32S3m+c889lxdeeIGKigruvfde9t9/f+bOndvhONdZ55v0qKAgh6OBM0RJXAcoLS2NOoTIkQM5ADkAOQA5ADlIxcqVK3nggQfYaaed4s/GJbPJJpswatQonnjiCf72t79x4IEHtnq+ZcuW8dJLLzF06FDOOOMMnnnmGYqKinjhhRda3H+bbbYhFovxv//9L75t7ty5xGIxysrKOla5iFAS1wH0wyoHIAcgByAHIAcgB62xcOFCJk+ezJdffsn111+fct9DDz2U5557juLiYjbaaKNW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JE4IIYQQIg9REtcBysvLow4hcuRADkAOQA5ADkAORG5REtcBiouLow4hcuRADkAOQA5ADkAORG5REtcBZsyYEXUIkSMHcgByAHIAcgCd72DV8lWdev6OXu9f//oXEydOxMw4//zz1yo//vjj2X333TnkkEPSXuLqnnvu4Z133mm27e2332bvvfdmxYoVGcXX3dBkv0IIIUSe0LuoN1cUXJGz610Wuyyj/ffaay/22msvzIwnnniCffbZh/322y9efu+993LBBRcwbtw4dt1117TOed9999G/f3++/e1vx7f17duXYcOGxZfk6qmoJU4IIYQQWWXTTTdl77335rLLLuOTTz7J+vm32mor7rnnHnr16pX1c+cTSuI6QElJSdQhRI4cyAHIAcgByAHIQSLXXHMNvXv35qKLLqK11aHeffddTjrpJCZMmMD48eM5/fTTWbBgQbz8+OOP57PPPuPOO+9k4sSJ/OIXv8Dd4122r7zySnzfhQsXcs4553DwwQdz8MEHM3nyZBYuXAjAhx9+GD/mkUce4ayzzuLggw/mhBNOYMmSJZ3qoTNREtcBzCzqECJHDuQA5ADkAOQA5CCRgQMHcs011/Dyyy8zderUFvd544032HLLLXnggQd48MEH+X//7//x85//PF5+77338q1vfYuTTz6ZqVOncuWVV2JmLZ7vjDPOoKioiCeffJInn3yS9dZbjzPPPBOALbfcMn7Miy++yI033si0adNYsmQJ9913XyfUPjcoiesAM2fOjDqEyJEDOQA5ADkAOQA5SGavvfbiuOOO4/rrr+f9999fq3z//ffnrLPOir//wQ9+wKuvvsry5cszuk51dTVvvPEGJ510UnzbiSeeyOuvv96stQ5gv/32o3fv3vTq1YuRI0euNWgin+jZTwR2kGXLlkUdQuTIgRyAHIAcgByAHLTEeeedx6uvvsrPfvYzHnnkkWZla9as4ZZbbuHtt9+md+/eNDY2EovFWLRoEZtuumna13jvvfcoKChg8803j2/bfPPNKSgooLa2ttkgik022ST+um/fvnn9mSmJE0IIIUSnUVhYyA033MBhhx3Gb3/722Zl559/Pp9//jn33HMP/fr1Y968eYwdO7bVZ+iywTrrfNMJWVBQ0GnXyQXqTu0AhYWFUYcQOXIgByAHIAcgByAHrbHVVltxwQUXcNddd/H222/H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\n",
      "text/plain": [
       "<Figure size 720x576 with 1 Axes>"
      ]
     },
     "metadata": {
      "needs_background": "light"
     },
     "output_type": "display_data"
    }
   ],
   "source": [
    "# Bar chart\n",
    "# Number of Detailed Occupations vs. Non-zero Demographic Groups\n",
    "bins = np.arange(0,33,4)\n",
    "df_dem = get_nonzero_dem_groups(occ_level='detailed')\n",
    "df_dem[LIST_GEO_LEVELS] = df_dem[[f'N_DEM_{col}' for col in LIST_GEO_LEVELS]].apply(pd.cut, bins=bins)\n",
    "\n",
    "fig = plt.figure(figsize=figsize)\n",
    "ax = plt.gca()\n",
    "\n",
    "width = -0.3\n",
    "# Scatter plot\n",
    "for geo_level in LIST_GEO_LEVELS:\n",
    "    df = df_dem[geo_level].value_counts().rename_axis('bins').reset_index()\n",
    "    ax.bar(x=(bins/4 + width)[:-1], height=df[geo_level], width=0.2, align='center', \n",
    "           color=dict_colors[geo_level], label=geo_level.capitalize())\n",
    "    width += 0.2\n",
    "\n",
    "# Grid and labels\n",
    "ax.set_xticks(bins[:-1]/4, labels=[f'{i}-{i+4}' for i in bins[:-1]])\n",
    "ax.set_xticks(bins/4 -0.5, minor=True)\n",
    "ax.set_ylim(0,610)\n",
    "ax.set_yticks(np.arange(0, 610, 50))\n",
    "ax.set_xlabel(\"Number of Average Non-zero Demographic Groups\")\n",
    "ax.set_ylabel(\"Count of Detailed Occupations\")\n",
    "\n",
    "ax.grid(which=\"major\", axis=\"y\", color=\"gray\", alpha=0.5, ls=\"--\")\n",
    "ax.grid(which=\"minor\", axis=\"x\", color=\"gray\", alpha=0.5, ls=\"--\")\n",
    "\n",
    "# Legend\n",
    "ax.legend(title='Geographic Level', ncol=1, fontsize=14, bbox_to_anchor=(1, 1), loc='upper right', frameon=True, framealpha=1)\n",
    "\n",
    "plt.savefig(os.path.join(FOLDER_FIGURES, \"Occ Count vs. Dem Groups.jpg\"), dpi=dpi, format='jpg')\n",
    "      \n",
    "plt.show()"
   ]
  },
  {
   "cell_type": "markdown",
   "id": "22160dfb",
   "metadata": {},
   "source": [
    "# Data Notes"
   ]
  },
  {
   "cell_type": "markdown",
   "id": "608e9f94",
   "metadata": {},
   "source": [
    "- In the BLS data, TOT_EMP with ** is treated as missing data while missing rows for specific state-occupation pairs are treated as 0 workers.\n",
    "- In ACS_EMP and ACS_DEM, some tracts have 0 workers.\n",
    "- In the CPS data, oversamples (CPSIDP = 0) are kept for ASECWT.\n",
    "- In the CPS data, missing DEM_GROUP data is treated as missing and not 0 because it's a sample and not the population.\n",
    "- '29-1024' has 0 workers in the BLS data"
   ]
  }
 ],
 "metadata": {
  "kernelspec": {
   "display_name": "Python 3 (ipykernel)",
   "language": "python",
   "name": "python3"
  },
  "language_info": {
   "codemirror_mode": {
    "name": "ipython",
    "version": 3
   },
   "file_extension": ".py",
   "mimetype": "text/x-python",
   "name": "python",
   "nbconvert_exporter": "python",
   "pygments_lexer": "ipython3",
   "version": "3.9.12"
  },
  "toc": {
   "base_numbering": 1,
   "nav_menu": {},
   "number_sections": true,
   "sideBar": true,
   "skip_h1_title": false,
   "title_cell": "Table of Contents",
   "title_sidebar": "Contents",
   "toc_cell": false,
   "toc_position": {
    "height": "calc(100% - 180px)",
    "left": "10px",
    "top": "150px",
    "width": "244.375px"
   },
   "toc_section_display": true,
   "toc_window_display": true
  }
 },
 "nbformat": 4,
 "nbformat_minor": 5
}
